使用Lucene搜索带有空格的术语

时间:2017-08-30 08:54:39

标签: java lucene whitespace

我尝试使用Lucene添加搜索功能,但似乎无法获得使用重要空白的索引。我有以下测试用例设置:

RAMDirectory directory = new RAMDirectory();
KeywordAnalyzer analyzer = new KeywordAnalyzer();
IndexWriterConfig config = new IndexWriterConfig(analyzer);
IndexWriter writer = new IndexWriter(directory, config);
Document doc = new Document();
doc.add(new TextField("content", "Bill Evans", Field.Store.NO));
writer.addDocument(doc);
writer.close();

IndexReader reader = DirectoryReader.open(directory);
IndexSearcher searcher = new IndexSearcher(reader);

QueryParser parser = new QueryParser("content", analyzer);
parser.setSplitOnWhitespace(false);
Query query = parser.parse("Bill E");

TopDocs docs = searcher.search(query, 1);
assertTrue(docs.totalHits > 0);

我使用的是Lucene 6.6.0,根据我的理解KeywordAnalyzer是我正在寻找的:

  

"&标记化#34;整个流作为单个令牌。这对于邮政编码,ID和某些产品名称等数据非常有用。

但我似乎无法获得包含空格的任何匹配文档。

关于如何解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:1)

当您编制索引时,您只有一个文档,其中包含一个字段且一个字词值为Bill Evans

当您要进行搜索时,TermQuery生成的QueryParser会尝试使用字词值Bill E进行搜索,并且该字词在索引中显然不存在,因此您将获得零命中。

如果用 - Bill Evans替换搜索字符串,您将获得结果。

请参考this question

首先,您需要分离索引和搜索问题。您只能搜索索引的内容。如果您在没有分成令牌的情况下索引全文而是在搜索时间 - 如果搜索时的输入字符串与索引中的输入字符串不同,则需要生成WildCardQueryFuzzyQueryPhraseQuery等。 TermQuery会搜索确切的字词值。

我的建议是存储全文值(没有令牌 - StringField会这样做)以及使用类似 - SimpleAnalyzer之类的内容生成其他令牌。

所以喜欢,

doc.add(new TextField("content", "Bill Evans", Field.Store.NO));
doc.add(new StringField("storedcontent", "Bill Evans", Field.Store.YES));

以上代码SimpleAnalyzer,您现在将拥有条款 - bill& evans  (以及作为存储字段的全文)如果您现在使用相同的分析器进行搜索,您的查询就像 - content:bill content:e&你会得到一个结果。

总而言之 - 系统按照您编码的方式工作:)

首先,要了解您的要求,以及您希望对该索引执行哪种查询。