我有一个产品数据库(足球),其中包含大约5k个产品。产品搜索的Lucene索引目前包含名称,类别,颜色和数字(ArtNo和EAN)。
问题的相关表示例:
| Name | Color | -------------------------------------------- | Nike Training football | red black | | Nike Match football | black white | --------------------------------------------
对于索引我创建了一个自定义分析器,因此我可以使用其他行为扩展StandardAnalyzer。目前,流的创建看起来像这样:
TokenStream result = new StandardTokenizer(Util.Version.LUCENE_29, reader );
result = new StandardFilter(result);
result = new LowerCaseFilter(result);
result = new StopFilter(true, result, stoptable );
return result;
分析器用于索引器和搜索器。
这是当前的搜索逻辑:
BooleanQuery booleanQuery = new BooleanQuery(true);
string[] terms = query.Split(' ');
foreach (string s in terms)
{
BooleanQuery subQuery = new BooleanQuery(true);
var nameQuery = new FuzzyQuery(new Term("Name", s), 0.9f);
nameQuery.SetBoost(6);
subQuery.Add(nameQuery, BooleanClause.Occur.SHOULD);
var colorQuery = new TermQuery(new Term("Color", s));
subQuery.Add(colorQuery, BooleanClause.Occur.SHOULD);
var categoryQuery = new FuzzyQuery(new Term("Category", s), 0.9f);
categoryQuery.SetBoost(2);
subQuery.Add(categoryQuery, BooleanClause.Occur.SHOULD);
var numbersQuery = new TermQuery(new Term("Numbers", s));
numbersQuery.SetBoost(10);
subQuery.Add(numbersQuery, BooleanClause.Occur.SHOULD);
booleanQuery.Add(subQuery, BooleanClause.Occur.MUST);
}
它已经以某种方式起作用了。
许多产品的名称或类别都包含用户刚刚搜索过的字词。 在这个例子中,我使用过" Nike Match football"。 (注意:我只翻译它用于SO,因为大多数术语在数据库中都是德语)
如果我搜索" Nike football red "我确实得到了结果。但如果搜索" Nike ball red "虽然这是用户搜索它的方式,但我还是得不到它。 Afaik Lucene无法搜索子串(除了通配符),因为它只比较令牌 - 我确实需要这样的东西。
我已使Name
和Category
模糊不清,并根据其相关性为每一栏提供了适当的推动。
我已经阅读了 Ngrams ,但我真的不知道如何正确使用它。将NGramTokenFilter
添加到自定义分析器时,索引器可以正常工作。这里的问题是,我不希望每列(只是名称和类别),并且激活它时结果非常奇怪。
如果我将result = new NGramTokenFilter(result, 3, 4);
添加到我的分析器并搜索" nike ball "它什么都不返回。
Ngrams是解决方案吗?我做错了什么?
您对如何改进产品搜索还有其他建议吗?
答案 0 :(得分:0)
我'不熟悉Ngrams,但我认为你的情况有两种方法:
<强> 1。在搜索中使用通配符
在您要搜索的字段上使用前缀或模糊查询。重要的是你使用TextField( Javadoc)因为这些字段将被分析(StringField不要)并用于全文搜索。基于此,应该可以使用多个不完全匹配的术语进行搜索。
<强> 2。使用不同领域的不同分析仪
您可以使用PerFieldAnalyzerWrapper Javadoc分析具有不同分析器的不同字段。定义哪个字段应该使用哪个分析仪进行分析,然后您就可以了。 但请注意,您使用相同的分析器进行索引和搜索(它的lucene最佳实践)
其他信息
如果您使用通配符和变音符号(德语yaaaay),您必须知道不会像普通查询一样分析通配符查询。 我遇到了同样的问题并用两种方式解决了这个问题:
在这两个字段中搜索BooleanQuery时。