0

我是 SOLR 的新手,正在实施它来搜索我们的产品目录。我正在品牌名称、显示名称和类别字段上创建 ngram 和边缘 ngram。

我正在使用 edismax 并将 qf 定义为 displayname_nge displayname_ng category_nge category_ng brandname_nge brandname_ng。

当我搜索“维生素 c”(不带引号)时,我得到了所有的维生素。如果我用引号括起来,那么我只会得到维生素 c。问题是我不能总是用引号将查询字符串括起来,因为一个人可能会输入“chewable Vitamin c”或“vendor x Vitamin c”。我已经尝试了 mm 参数,但没有运气。我也尝试过应用不同的提升水平,但仍然没有得到预期的结果。

任何建议将不胜感激。谢谢

4

3 回答 3

1

是否有理由只使用 ngrams 字段进行搜索?我不确定这是否是您的问题,但您可能想查看 schema.xml 中的 ngrams 分析配置。我的一个索引中的一个如下所示:

<fieldType name="ngram" class="solr.TextField" >
<analyzer type="index">        
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
    <tokenizer class="solr.LowerCaseTokenizerFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
</analyzer>
<analyzer type="query">        
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
    <tokenizer class="solr.LowerCaseTokenizerFactory"/>
</analyzer>
</fieldType>

虽然您可以看到这实际上是使用更安全EdgeNGramFilterFactory的,但这里需要注意的重要一点是minGramSize="2"。这意味着在索引过程中只会创建至少两个字符的克。“c”这个词?那根本没有任何克数。虽然您可以设置minGramSize="1"和重建索引,但单字符grams 是一个非常糟糕的主意,因为您对“c”的搜索将匹配任何以“c”开头的单词(或包含带有“c”的字母NGramFilterFactory)的文档。

如果您当前使用带有 的 NGrams minGramSize="2",则搜索“ca”将找到任何包含按该顺序连续包含字母“ca”的单词的任何文档。这也可能不是您想要的。

我的首要建议是放弃 ngram 以支持更普通的文本字段。是否要保留 edge-ngrams 以获得更好的截断支持取决于您,但我怀疑如果 Text 字段至少在混合中,您会有更好的运气。

您还可以查看 StackOverflow 上的这个问题:“我可以在 Solr 中保护短词免受 n-gram 过滤器的影响吗?” 如果您想进一步研究 ngram。

此外,您应该考虑使用 Solr 的内置分析工具来找出您的搜索失败的地方。您选择一个字段或字段类型,并为输入到索引中的内容和正在搜索的内容提供值。它将向您展示分析如何针对这两个值进行,因此您可以了解每个字符串是如何分解的,以及它为什么会创建或不创建匹配的标记。该工具的 URL 取决于您是否处于多核环境中,但如果您访问 Solr 的 Web 界面,您应该能够Analysis在左侧找到该链接。

更新:

现在我从你那里得到了更多的细节并且正在再次考虑它,你得到的结果是非常可以解释的。

使用minGramSize="1",您对 'vitamin c' 的未引用搜索正在查找包含单词 'vitamin'(或包含 'vitamin' 的更长单词)和单词 'c'(或包含 'c' 的更长单词)的记录。由于大多数记录可能在某处有一个“c”,这几乎不是一个限制因素,您的结果将非常接近或与您仅使用“维生素”一词的结果非常接近或完全相同。

引用的“维生素 c”搜索中,“c”现在必须出现在维生素之后的单词中,这使其成为更有用的搜索,但仍然不是很好。您应该能够通过查找在维生素后面有一个不是维生素名称的单词的记录来测试这一点。例如,在搜索“vitamin b”时应该找到一条提及“vitamin tablet”的记录(因为“tablets”中有一个“b”)。并且在搜索“维生素c”时,应找到提及“维生素图表”或“维生素缺乏症”的记录。

这样做的结果是,我强烈建议将一组用于搜索的字段与自动完成的字段分开。带有的 NGramminGramSize="1"不会为您提供实际搜索步骤的合理结果。

于 2014-05-15T16:42:42.760 回答
0

其他选项是使用 edismax - 'mm',在那里你可以给出匹配的 %。如果你付出100%,它会给你准确的匹配。75% 会为您提供维生素清单...您可以根据需要以编程方式处理 %

于 2015-01-09T05:41:57.123 回答
-2

您可以考虑这样替换查询关键字:“'vitamin c' Vitamin c”。在这种情况下,匹配 'vitamin c' 的记录可以比分别匹配 'vitamin' 和 'c' 的记录获得更高的分数。您的搜索结果仍将返回所有匹配的记录。请看看这是否有帮助,并随时发表评论。

于 2020-03-19T02:24:53.900 回答