我是Lucene的新手,我在创建简单的代码来查询文本文件集时遇到了一些问题.
我试过这个例子,但是与新版本的Lucene不兼容.
UDPATE: 这是我的新代码,但它仍然无法正常工作.
Lucene是一个非常大的主题,有很多类和方法需要覆盖,如果不了解至少一些基本概念,通常不能使用它.如果您需要快速可用的服务,请改用Solr.如果您需要完全控制Lucene,请继续阅读.我将介绍一些代表它们的核心Lucene概念和类.(有关如何在内存中读取读取文本文件,例如,信息这个文章).
无论你在Lucene做什么 - 索引或搜索 - 你都需要一台分析仪.分析器的目标是将输入文本标记化(分成单词)和词干(获得单词的基础).它还会抛出最常用的单词,如"a","the"等.您可以找到超过20种语言的分析器,或者您可以使用SnowballAnalyzer并将语言作为参数传递.
要为英语创建SnowballAnalyzer实例,请执行以下操作:
Analyzer analyzer = new SnowballAnalyzer(Version.LUCENE_30, "English");
如果您要使用不同语言索引文本,并希望自动选择分析器,则可以使用tika的LanguageIdentifier.
您需要在某处存储索引.这有两个主要可能性:内存索引(易于尝试)和磁盘索引(最常见的索引).
使用接下来的两行中的任何一行:
Directory directory = new RAMDirectory(); // RAM index storage Directory directory = FSDirectory.open(new File("/path/to/index")); // disk index storage
如果要添加,更新或删除文档,则需要IndexWriter:
IndexWriter writer = new IndexWriter(directory, analyzer, true, new IndexWriter.MaxFieldLength(25000));
任何文档(在您的情况下为文本文件)都是一组字段.要创建包含文件信息的文档,请使用以下命令:
Document doc = new Document(); String title = nameOfYourFile; doc.add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED)); // adding title field String content = contentsOfYourFile; doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED)); // adding content field writer.addDocument(doc); // writing new document to the index
Field
构造函数采用字段名称,文本和至少 2个参数.首先是一个标志,显示Lucene是否必须存储此字段.如果等于Field.Store.YES
,则可以从索引中获取所有文本,否则只会存储有关它的索引信息.
第二个参数显示Lucene是否必须索引此字段.使用Field.Index.ANALYZED
你要搜索的任何领域.
通常,您使用上述两个参数.
IndexWriter
工作完成后别忘了关闭你的工作:
writer.close();
搜索有点棘手.您将需要几个类:Query
并QueryParser
从字符串中进行Lucene查询,IndexSearcher
进行实际搜索,TopScoreDocCollector
存储结果(将其IndexSearcher
作为参数传递)并ScoreDoc
迭代结果.下一个片段显示了这一切是如何组成的:
IndexSearcher searcher = new IndexSearcher(directory); QueryParser parser = new QueryParser(Version.LUCENE_30, "content", analyzer); Query query = parser.parse("terms to search"); TopScoreDocCollector collector = TopScoreDocCollector.create(HOW_MANY_RESULTS_TO_COLLECT, true); searcher.search(query, collector); ScoreDoc[] hits = collector.topDocs().scoreDocs; // `i` is just a number of document in Lucene. Note, that this number may change after document deletion for (int i = 0; i < hits.length; i++) { Document hitDoc = searcher.doc(hits[i].doc); // getting actual document System.out.println("Title: " + hitDoc.get("title")); System.out.println("Content: " + hitDoc.get("content")); System.out.println(); }
注意QueryParser
构造函数的第二个参数- 它是默认字段,即如果没有给出限定符则将搜索的字段.例如,如果您的查询是"title:term",Lucene将在所有文档的字段"title"中搜索单词"term",但如果您的查询只是"term",则会在默认字段中搜索,在这种情况下 - "内容".有关更多信息,请参阅Lucene查询语法.
QueryParser
也将分析器作为最后一个参数.这必须与您用于索引文本的分析器相同.
你必须知道的最后一件事是TopScoreDocCollector.create
第一个参数.它只是一个数字,表示您要收集的结果数量.例如,如果它等于100,Lucene将仅收集第一个(按分数)100个结果并删除其余部分.这只是一种优化行为 - 您收集最佳结果,如果您对此不满意,则重复搜索更大的数字.
最后,不要忘记关闭搜索器和目录,以免丢失系统资源:
searcher.close(); directory.close();
编辑:另请参见IndexFiles演示类从Lucene的3.0来源.