我是SOLR的新手,正在实现它来搜索我们的产品目录。我正在创建品牌名称,显示名称和类别字段上的图形和边缘图形。
我使用edismax并将qf定义为displayname_nge displayname_ng category_nge category_ng brandname_nge brandname_ng
当我搜索"维生素c"(不带引号)时,我得到了所有的维生素。如果我用引号把它括起来,那么我只能得到维生素c。问题是,我不能总是用引号把查询字符串括起来,因为一个人可能会输入"可咀嚼的维生素c",或者"供应商x维生素c"。我试过mm参数,但运气不好。我也试过应用不同的提升水平,仍然没有得到预期的结果。
任何建议都将非常感谢。谢谢你
是否有理由只使用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"
并重建索引,但单字符图是一个非常糟糕的主意,因为您搜索'c'将匹配任何以'c'开头的单词(或与NGramFilterFactory
包含字母'c')的文档。
如果您当前使用的是minGramSize="2"
的NGrams,那么搜索"ca"将找到包含字母"ca"的任何单词的任何文档。这可能也不是你想要的。
我的首要建议是放弃图形,使用更普通的文本字段。是否要保留edge-ngram以获得更好的截断支持取决于您,但我怀疑如果至少在混合中包含Text字段,您会有更好的运气。
你也可以看看StackOverflow上的这个问题:"我能在Solr中保护短单词不受n-gram过滤器的影响吗?"如果你想进一步研究n-gram的话。
此外,您应该考虑使用Solr的内置分析工具来找出搜索失败的地方。您可以选择一个字段或fieldType,并为输入到索引中的内容和正在搜索的内容提供值。它将向您展示如何对这两个值进行分析,以便您可以看到每个字符串是如何分解的,以及为什么它会或不会创建匹配的令牌。该工具的URL取决于你是否在多核环境中,但如果你去Solr的web界面,你应该能够在左侧找到Analysis
链接。
更新:
现在我从你那里得到了更多的细节,我又重新考虑了一下,你得到的结果是很容易解释的。
对于minGramSize="1"
,您对"维生素c"的未引用搜索正在查找单词"维生素"(或包含"维生素"的较长单词)和单词"c"(或包含"c"的较长单词)的记录。由于大多数记录可能在某个地方有一个"c",这几乎不是一个限制因素,您的结果将非常接近或完全相同,您的结果只包含"维生素"这个词。
在加引号的搜索"维生素c"时,"c"现在必须出现在维生素之后的一个单词中,使它成为一个更有用的搜索,但仍然不是很好。你应该能够通过找到在维生素后面有一个不是维生素名称的单词的记录来验证这一点。例如,当搜索"维生素b"时,应该找到提到"维生素片"的记录(因为"片"中有一个"b")。在搜索"维生素c"时,应注明"维生素表"或"维生素缺乏症"。
这样做的结果是,我强烈建议将一组用于搜索的字段与自动完成的字段分开。对于实际的搜索步骤,带有minGramSize="1"
的ngram不会给你合理的结果。
另一个选择是使用edismax - 'mm',在那里您可以给出匹配的%。如果你给出100%,它会给出准确的匹配。75%的人会给你维他命清单您可以根据需要以编程方式处理%
您可以考虑这样替换查询关键字:"'vitamin c' vitamin c"。在这种情况下,匹配"维生素c"的记录可以比单独匹配"维生素"one_answers"c"的记录获得更高的分数。您的搜索结果仍将返回所有匹配的记录。请看看这是否有帮助,并随时评论。