Lucene基础(二)--索引的操作
2015-05-31 15:07
316 查看
索引的操作
我们建立所有就是要达到快速检索的目的,对数据能够方面便的查找,和数据库类似,索引也有自己的相关增删改查的操作。在索引的增删改查中,增删改属于写操作,主要是有IndexWrite提供的方法处理;而查显而易见,读操作,使用IndexSeacher 提供的方法来实现。在Lucene的官方文档找到 org.apache.lucene.index.IndexWriter 这个类,我们就可以看到他很多方法。
创建索引
如同上一章里面的代码,创建索引时先建立文件,创建索引的域,再使用IndexWriter的addDocument()方法就可以了,核心代码如下:iwriter = new IndexWriter(directory, new IndexWriterConfig(version, new StandardAnalyzer(version))); for(String text : content){ doc = new Document(); //使用的field 有很多类型,理解他们的区别 例如:TextField 和 StringField等 doc.add(new TextField("content", text,Field.Store.YES)); iwriter.addDocument(doc); }
索引删除
索引删除包括只删除索引下面的document和删除索引文件在IndexWriter有如下一些方法
deleteAll() 删除索引中所有的documents
deleteDocuments(Query… queries) 按照提供的Query 删除documents
deleteDocuments(Term… terms) 按照短语删除documents
deleteUnusedFiles() 删除所有不再使用index的文件
forceMergeDeletes() 删除处于已经删除的状态documents,由此可见,之前的删除文档的方法并没有真正的删除掉的documents,只是标记删除,我个人理解是类似逻辑上的删除
forceMergeDeletes(boolean doWait) 删除过程中指明是否阻塞,直到操作完成
索引更新
更新操作也是一样,查看文档就有,这里截个图:索引查询
Query索引查询的时候可以使用Query的实现子类来创建查询,执行IndexSearcher的search方法来查询,也可以使用QueryParse类来构造查询.
分页
方式1:在scoreDoc中进行分页,数据一次性查出来,在结果集分页,结果集较大时容易溢出
方式2:使用searcheAfter,等价查询的次数,但是不会出现查询结果溢出,推荐,类似数据库中的分页查询
这个类似数据库中的查询,可以对结果集分页显示,类似方式一,查询的时候直接分页,类似方式二 。
索引操作实例
package lucene_demo03; import java.io.IOException; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.TextField; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.Term; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.util.Version; /** * *关于索引的查询(分页查询) *方式1:在scoreDoc中进行分页,数据一次性查出来,在结果集分页,结果集较大时容易溢出 *方式2:使用searcheAfter,等价查询的次数,但是不会出现查询结果溢出,推荐,类似数据库中的分页查询 * @author YipFun */ public class LuceneDemo03 { private static final Version version = Version.LUCENE_4_9; private Directory directory = null; private DirectoryReader ireader = null; private IndexWriter iwriter = null; //测试数据 private String[] content = { "hello lucene", "I love coding", "I can play basketball", "I can play football", "I can play dota" }; /** * 构造方法 */ public LuceneDemo03() { directory = new RAMDirectory(); } /** * 创建索引 */ public void createIndex(){ Document doc = null; try { iwriter = new IndexWriter(directory, new IndexWriterConfig(version, new StandardAnalyzer(version))); for(String text : content){ doc = new Document(); //使用的field 有很多类型,理解他们的区别 例如:TextField 和 StringField doc.add(new TextField("content", text,Field.Store.YES)); iwriter.addDocument(doc); } } catch (IOException e) { e.printStackTrace(); }finally{ try { if(iwriter != null) iwriter.close(); } catch (IOException e) { e.printStackTrace(); } } } public IndexSearcher getSearcher(){ try { if(ireader==null) { ireader = DirectoryReader.open(directory); } else { DirectoryReader tr = DirectoryReader.openIfChanged(ireader) ; if(tr!=null) { ireader.close(); ireader = tr; } } return new IndexSearcher(ireader); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * * @param field * @param term * @param num */ public void searchByTerm(String field,String term,int num){ IndexSearcher isearcher = getSearcher(); //注意query的实现类和QueryParse的用法的区别 TermQuery query = new TermQuery(new Term(field, term)); ScoreDoc[] hits; try { //注意searcher的几个方法 hits = isearcher.search(query, null, num).scoreDocs; // Iterate through the results: for (int i = 0; i < hits.length; i++) { Document hitDoc = isearcher.doc(hits[i].doc); System.out.println("This is the text to be indexed="+hitDoc.get("content")); } } catch (IOException e) { e.printStackTrace(); } } /** * 区别与上一种查询,使用QueryParser的parse方法构造一个Query传递给方式使用 * @param query * @param num */ public void searchByQueryParse(Query query,int num) { try { IndexSearcher searcher = getSearcher(); TopDocs tds = searcher.search(query, num); System.out.println("一共查询了:"+tds.totalHits); for(ScoreDoc sd:tds.scoreDocs) { Document doc = searcher.doc(sd.doc); System.out.println("This is the text to be indexed="+doc.get("content")); } } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 第一中分页方式,对ScoreDoc进行分页 * @param query * @param pageIndex 从1开始,即第一页 * @param pageSize 分页大小 * @param num search top n hits */ public void searchForPage(Query query ,int pageIndex,int pageSize,int num){ try { IndexSearcher searcher = getSearcher(); TopDocs tds = searcher.search(query, num); System.out.println("一共查询了:"+tds.totalHits); //对ScoreDoc分页 int start = (pageIndex-1)*pageSize; int end = pageIndex*pageSize; ScoreDoc scoreDocs[] = tds.scoreDocs; for(int i=start;i<end;i++) { Document doc = searcher.doc(scoreDocs[i].doc); System.out.println("This is the text to be indexed="+doc.get("content")); } } catch (CorruptIndexException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 使用searchAfter 实现在查询的时候的分页 * @param query * @param pageIndex * @param pageSize * @throws IOException */ public void searchForPageByAfter(Query query ,int pageIndex,int pageSize) throws IOException{ IndexSearcher searcher = getSearcher(); //先获取上一页的最后一个元素 ScoreDoc lastSd = getLastScoreDoc(pageIndex, pageSize, query, searcher); TopDocs tds = searcher.searchAfter(lastSd,query, pageSize); for(ScoreDoc sd:tds.scoreDocs) { Document doc = searcher.doc(sd.doc); System.out.println("This is the text to be indexed="+doc.get("content")); } } /** * 返回分页查询的上一条 * @param pageIndex * @param pageSize * @param query * @param indexSearcher * @return */ private ScoreDoc getLastScoreDoc(int pageIndex,int pageSize,Query query,IndexSearcher searcher){ if(pageIndex==1)return null;//如果是第一页就返回空 int num = pageSize*(pageIndex-1);//获取上一页的数量 TopDocs tds = null; try { tds = searcher.search(query, num); } catch (IOException e) { e.printStackTrace(); } return tds.scoreDocs[num-1]; } public static void main(String[] args) throws ParseException, IOException { LuceneDemo03 ld = new LuceneDemo03(); ld.createIndex(); ld.searchByTerm("content","play",500); System.out.println("==============1======================"); QueryParser parser = new QueryParser(version, "content", new StandardAnalyzer(version)); Query q = parser.parse("play");//研究下parse的语法 ld.searchByQueryParse(q,500); System.out.println("===============2====================="); ld.searchForPage(q, 1, 2, 500);//从第一页开始 System.out.println("================3===================="); ld.searchForPageByAfter(q, 1, 2);//从第一页开始 System.out.println("================4===================="); } }
相关文章推荐
- 数据库分页查询语句数据库查询
- php检索或者复制远程文件的方法
- jquery向上向下取整适合分页查询
- 高效的SQLSERVER分页查询(推荐)
- java Lucene 中自定义排序的实现
- mysql、mssql及oracle分页查询方法详解
- SQL Server 分页查询通用存储过程(只做分页查询用)
- mysql分页原理和高效率的mysql分页查询语句
- ASP.Net中英文复合检索文本框实现思路及代码
- 使用python实现正则匹配检索远端FTP目录下的文件
- MongoDB入门教程之索引操作浅析
- 从零开始使用Hubbledotnet进行全文搜索-前言
- ctags --- 每天一个 Linux 命令
- Lucene整合"庖丁解牛"中文分词包
- JAVA lucene全文检索工具包的理解与使用 分享
- Lucene:基于Java的全文检索引擎简介
- 使用Lucene 3.3.0的结构遍历TokenStream的内容.
- Sql server中一些Select检索高级用法
- ORACLE数据库分页查询/翻页 最佳实践
- Oracle分页查询三种方式