我是Apache Solr的新手。我正在尝试为以下查询找出令牌生成器,过滤器和查询参数,但还无法确定是否可行(仍在阅读所有文档):
我有两个字段-title
和description
。我们想在以下位置进行搜索:
1. title
中的匹配比description
中的匹配具有更大的相关性。
2.完整的单词匹配优先于所有其他单词(对于查询kit
,kit
优先于kitchen
)。
3.以查询字段开头的索引条目优先于仅包含该字段的索引条目(对于查询goo
,good
优先于Magoo
)。
这甚至可能吗?如果是这样,我该怎么办?
答案 0 :(得分:1)
字段之间的加权不是令牌生成器或过滤器关心的问题-它们的工作是获取一些输入文本,将其拆分为令牌(令牌),然后通过一系列处理步骤(过滤器)运行它。 / p>
edismax and dismax query parsers有一个名为qf
的参数,它允许您提供应查询的字段列表,并为每个字段提供单独的权重-允许您精确调整要查询的权重。给每个领域。 qf=title^5 description
在title
字段中的点击量比description
中的字段高五倍-其他所有内容都是相同的(但它们通常是不相同的,因为您没有编制索引两个字段中包含相同的内容。
这就是评分不是一门精确科学的原因,因此,如果您想使用某种相关性评分(即,点击不同的单词会得到不同的评分),则必须调整这些权重以适合寻找您的排名。在调整得分时,将debugQuery=true
附加到查询中非常有帮助,因为它将准确显示每个术语对文档的最终得分有多大贡献。
您的第一个条件title
与description
通过使用带有StandardTokenizer和小写过滤器的TextField来解决(取决于您要查找的内容,还可以选择词干,同义词等)。 。
在下面给出的示例中,您(可能)还希望使用小写过滤器,但是为了使示例紧凑,我省略了它。
通过使用具有EdgeNGramFilter的第二种字段类型,然后具有使用该字段类型的两个新字段-title_edge
和description_edge
来解决第二种情况。
这和下面的NGramFilter示例都使用type="index"
属性,因为通常只有在索引时扩展ngram才有意义。否则,以相同字母开头(或对于NGram过滤器,包含相同字母)的任何两个单词都将匹配。
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="40" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
</analyzer>
通过使用第三组字段title_ngram
和description_ngram
来解决第三个条件,这些字段的顺序为NGramFilter:
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.NGramFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
</analyzer>
请注意,NGramFilter将导致生成很多令牌,需要更多的存储空间,并且在生成匹配项时使搜索处理更多的令牌。这可能与您的用例无关,也可能无关。
话虽这么说,但要匹配单词中的内部术语(尤其是非常短的字符串)要说些什么。他们可能会在用户无法理解为什么匹配文档的情况下给出结果,因为它可能在某处很小的匹配项(键入查询时为单个字母)。只需搜索“ c”以找到有关编程语言的内容,就会获得每个包含c的单词的匹配(但幸运的是,如果您对字段进行了适当的提升,则确切的匹配应该位于顶部)。 / p>