如何在Lucene.NET中进行部分单词搜索?

时间:2009-12-04 03:59:19

标签: c# lucene lucene.net

我有一个相对较小的索引,包含大约4,000个位置。除此之外,我正在使用它来填充搜索表单上的自动填充字段。

我的索引包含带有包含

等值的位置字段的文档
  • 俄亥俄州
  • 俄亥俄州代顿
  • 俄亥俄州都柏林
  • 俄亥俄州哥伦布市

我希望能够输入“ohi”并显示所有这些结果,现在没有任何显示,直到我输入完整的单词“ohio”。

我正在使用Lucene.NET v2.3.2.1,我的代码的相关部分如下设置我的查询....

BooleanQuery keywords = new BooleanQuery();
QueryParser parser = new QueryParser("location", new StandardAnalyzer());
parser.SetAllowLeadingWildcard(true);
keywords.Add(parser.Parse("\"*" + location + "*\""), BooleanClause.Occur.SHOULD);
luceneQuery.Add(keywords, BooleanClause.Occur.MUST);

简而言之,我想让它像LIKE子句一样工作,类似于

SELECT * from Location where Name LIKE '%ohi%'

我可以用Lucene做到这一点吗?

3 个答案:

答案 0 :(得分:14)

尝试此查询:

parser.Parse(query.Keywords.ToLower() + "*")

答案 1 :(得分:1)

是的,这可以做到。但是,领先的通配符可能会导致查询速度变慢。检查documentation。此外,如果要将整个字符串(例如“Dayton,Ohio”)索引为单个标记,则大多数查询将退化为前导前缀查询。使用像StandardAnalyzer这样的标记器(我想你已经在做了)将减少对前导通配符的要求。

如果出于性能原因不想使用前导前缀,可以尝试索引ngrams。这样,就不会有任何前导通配符查询。 ngram(假设长度仅为4)tokenizer将为“Dayton Ohio”创建标记为“dayt”,“ayto”,“yton”等等。

答案 2 :(得分:0)

更重要的是首先用部分单词填充索引。您的分析器需要在分析时将部分关键字放入索引中(并希望将它们加权到低于完整关键字的位置)。

lucene索引查找树从左到右工作。如果你想在关键字的中间搜索,你可以在分析时将其分解。问题是部分关键字通常会破坏您的索引大小。

人们通常使用真正有创意的分析器来分解根词(取消前缀和后缀)中的单词。

深入了解lucene。这是件好事。 : - )