lucene3.0创建索引及多目录搜索详解 lucene 6.0 创建索引
创建索引:
Java code
public void index() throws CorruptIndexException,LockObtainFailedException, IOException {// 索引目录 File indexDir = new File("D:/workspace/code/java/TestLucene3/index/txt/test/");// 注意:这里建立索引用的分词方法,在搜索时分词也应该采用同样的分词方法。不然搜索数据可能会不正确// 使用Lucene自带分词器 Analyzer luceneAnalyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);// 第一个参数是存放索引文件位置, 第二个参数是使用的分词方法, 第三个:true,建立全新的索引,false,建立增量索引。// IndexWriter indexWriter = new IndexWriter(indexDir, luceneAnalyzer, true);// 第一个参数是存放索引目录有FSDirectory(存储到磁盘上)和RAMDirectory(存储到内存中), 第二个参数是使用的分词器, 第三个:true,建立全新的索引,false,建立增量索引,第四个是建立的索引的最大长度。 IndexWriter indexWriter = new IndexWriter(FSDirectory.open(indexDir),luceneAnalyzer, true, IndexWriter.MaxFieldLength.LIMITED);// 索引合并因子// SetMergeFactor(合并因子)// SetMergeFactor是控制segment合并频率的,其决定了一个索引块中包括多少个文档,当硬盘上的索引块达到多少时,// 将它们合并成一个较大的索引块。当MergeFactor值较大时,生成索引的速度较快。MergeFactor的默认值是10,建议在建立索引前将其设置的大一些。 indexWriter.setMergeFactor(100);// SetMaxBufferedDocs(最大缓存文档数)// SetMaxBufferedDocs是控制写入一个新的segment前内存中保存的document的数目,// 设置较大的数目可以加快建索引速度,默认为10。 indexWriter.setMaxBufferedDocs(100);// SetMaxMergeDocs(最大合并文档数)// SetMaxMergeDocs是控制一个segment中可以保存的最大document数目,值较小有利于追加索引的速度,默认Integer.MAX_VALUE,无需修改。// 在创建大量数据的索引时,我们会发现索引过程的瓶颈在于大量的磁盘操作,如果内存足够大的话,// 我们应当尽量使用内存,而非硬盘。可以通过SetMaxBufferedDocs来调整,增大Lucene使用内存的次数。 indexWriter.setMaxMergeDocs(1000);// SetUseCompoundFile这个方法可以使Lucene在创建索引库时,会合并多个 Segments 文件到一个.cfs中。// 此方式有助于减少索引文件数量,对于将来搜索的效率有较大影响。// 压缩存储(True则为复合索引格式) indexWriter.setUseCompoundFile(true);long startTime = new Date().getTime();String temp = "";// 增加索引字段//// 在Field中有三个内部类:Field.Index,Field.Store,Field.termVector,而构造函数也用到了它们。// 参数说明:// Field.Store:// Field.Store.NO:表示该Field不需要存储。// Field.Store.Yes:表示该Field需要存储。// Field.Store.COMPRESS:表示使用压缩方式来存储。// Field.Index:// Field.Index.NO:表示该Field不需要索引。// Field.Index.TOKENIZED:表示该Field先被分词再索引。// Field.Index.UN_TOKENIZED:表示不对该Field进行分词,但要对其索引。// Field.Index.NO_NORMS:表示该Field进行索引,但是要对它用Analyzer,同时禁止它参加评分,主要是为了减少内在的消耗。// TermVector这个参数也不常用,它有五个选项。// Field.TermVector.NO表示不索引Token的位置属性;// Field.TermVector.WITH_OFFSETS表示额外索引Token的结束点;// Field.TermVector.WITH_POSITIONS表示额外索引Token的当前位置;// Field.TermVector.WITH_POSITIONS_OFFSETS表示额外索引Token的当前和结束位置;// Field.TermVector.YES则表示存储向量。// 增加文档 Field相当于增加数据库字段一样检索,获取都需要的内容,直接放index中,不过这样会增大index,保存文件的txt内容 /*** Field.Store 表示“是否存储”,即该Field内的信息是否要被原封不动的保存在索引中。* Field.Index 表示“是否索引”,即在这个Field中的数据是否在将来检索时需要被用户检索到,一个“不索引”的Field通常仅是提供辅助信息储存的功能。* Field.TermVector 表示“是否切词”,即在这个Field中的数据是否需要被切词。*/Field fieldPath = new Field("path", "", Field.Store.YES, Field.Index.NO);Field fieldBody = new Field("content", temp, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS);Field fieldId = new Field("id", "", Field.Store.YES, Field.Index.NOT_ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS);Document document = new Document();// 做测试,循环100000遍建索引。也可以读取文件内容建索引 for (int i=0; i<100000; i++) {document = new Document();temp = "王熙凤历幻返金陵 甄应嘉蒙恩还玉阙";fieldPath.setValue("D:\workspace\code\java\TestLucene3\txt\" + i + ".txt");fieldBody.setValue(temp);fieldId.setValue(String.valueOf(i));document.add(fieldPath);document.add(fieldBody);document.add(fieldId);indexWriter.addDocument(document);i++;}//optimize()方法是对索引进行优化 indexWriter.optimize();indexWriter.close();// 若需要从索引中删除某一个或者某一类文档,IndexReader提供了两种方法:// reader.DeleteDocument(int docNum)// reader.DeleteDocuments(Term term)// 前者是根据文档的编号来删除该文档,docNum是该文档进入索引时Lucene的编号,是按照顺序编的;后者是删除满足某一个条件的多个文档。// 在执行了DeleteDocument或者DeleteDocuments方法后,系统会生成一个*.del的文件,该文件中记录了删除的文档,但并未从物理上删除这些文档。此时,这些文档是受保护的,当使用Document// doc = reader.Document(i)来访问这些受保护的文档时,Lucene会报“Attempt to access a// deleted document”异常。如果一次需要删除多个文档时,可以用两种方法来解决:// 1. 删除一个文档后,用IndexWriter的Optimize方法来优化索引,这样我们就可以继续删除另一个文档。// 2. 先扫描整个索引文件,记录下需要删除的文档在索引中的编号。然后,一次性调用DeleteDocument删除这些文档,再调用IndexWriter的Optimize方法来优化索引。long endTime = new Date().getTime();System.out.println("n这花费了" + (endTime - startTime) + " 毫秒增加到索引!");}
查询:
Java code
/*** 查询** @param String word 关键词* @param String filedName 域字段* @param String indexDir 索引位置* @throws CorruptIndexException* @throws IOException* @throws ParseException* @auther <a href="mailto:gaoxuguo@feinno.com">Gao XuGuo</a> Nov 30, 2009* 2:56:42 PM*/public List<Map<String, String>> search(String indexDir)throws CorruptIndexException, IOException, ParseException {File file = new File(indexDir);IndexSearcher is = new IndexSearcher(FSDirectory.open(file), true);String field = "content";BooleanQuery bq = new BooleanQuery();QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, field,new StandardAnalyzer(Version.LUCENE_CURRENT));Query query = parser.parse("content:王熙凤");Query q = new TermQuery(new Term("id","100"));bq.add(q,Occur.SHOULD);bq.add(query,Occur.SHOULD);// 100表示取前100条数据 TopScoreDocCollector collector = TopScoreDocCollector.create(100, true);long start = new Date().getTime();// start time/*** Lucene内置了三个Filter子类:* 1)DateFilter使搜索只限于指定的日期域的值在某一时间范围内的文档空间里* 2)QueryFilter把查询结果做为另一个新查询可搜索的文档空间* 3)CachingWrappperFilter是其他过滤器的装饰器,将结果缓存起来以便再次使用,从而提高性能。**/String[] dirs = {indexDir};MultiSearcher ms = this.getMultiSearcher(dirs);ms.search(bq, collector);// is.search(bq, collector); ScoreDoc[] docs = collector.topDocs().scoreDocs;Document doc;for (ScoreDoc sd : docs) {doc = is.doc(sd.doc);// 取得doc里面的Field并从doc里面读取值 for (Fieldable fa : doc.getFields()) {System.out.print(fa.name() + "=" + doc.get(fa.name()) + " ");}System.out.println();}long end = new Date().getTime();if(is != null) is.close();System.out.println("找到 " + collector.getTotalHits()+ " 条数据,花费时间 " + (end - start)+ " 秒");return null;}
少发了一个方法:
Java code
/*** 得到MultiSearcher多目录查询实例** @param String[] dirs 要查询的索引目录。** @return MultiSearcher* @throws IOException* @auther <a href="mailto:gaoxuguo@feinno.com">Gao XuGuo</a>* Jan 22, 2010 3:44:16 PM*/private MultiSearcher getMultiSearcher(String[] dirs) throws IOException {// 多目录 IndexSearcher [] searchers = new IndexSearcher[dirs.length];int i = 0;for (String dir : dirs) {searchers[i] = new IndexSearcher(FSDirectory.open(new File(dir)), true);i++;}// 多目录查询 return new MultiSearcher(searchers);}
更多阅读
DNF全新系统风暴竞技场详解及奖励介绍 风暴部落 竞技场
DNF游戏最近推出的活动确实挺多的,先是说要推出守护者祭坛,现在又推出了一个风暴竞技场系统。大混战模式,最后生存下来的人会受到万人敬仰哦,其中的奖励自然也是非常强力的。DNF全新系统风暴竞技场详解及奖励介绍——步骤/方法DNF
三星s5830刷机教程详解免费升级安装安卓4.0 ROM 三星5830系统怎么升级
这个刷机教程是我好不容易从网上找来的,其他的都不是很详细,有些不敢刷,只有这篇还算可以。我亲自试验了一下,果然刷成功了,不敢吃独食,这就给大家分享一下。三星s5830刷机教程详解免费升级安装安卓4.0 ROM——前言:三星s5830手机是2011年
wow6.0冰法pvp天赋属性雕文详解 5.4冰法pvp天赋
wow6.0冰法pvp天赋属性雕文详解——简介pvp与pve是截然不同的,人不少npc不会傻站着让你抽。总结了一下,来和大家分享下冰法的pvp技巧,宗旨就一个:冰法讲究的是控制(战场控场,插旗控人),控制好的话,一波爆发直接带走。熟透这个宗旨以后,你会发
ps教程:蒙版的类型及应用详解
蒙版在PS里的应用相当广泛,蒙版最大的特点就是可以反复修改,却不会影响到本身图层的任何构造。如果对蒙版调整的图像不满意,可以去掉蒙版原图像又会重现。真是非常神奇的工具。ps教程:蒙版的类型及应用详解——工具/原料photoshop5.0以
如何分辨魔障与业障:现象、起因及对治方法详解
特别提示:本文节选自成观法师地藏法门系列讲义中《三、修行魔障与对治法门》,全文链接:http://www.folou.com/viewthread.php?tid=436703&extra=&page=1修行魔障与对治法门甲、修行的各种障碍修行地藏法门最主要的功能或目的