零件号中的 Solr 搜索破折号

Solr search dash in part number

我在如何构建 Solr 查询或如何设置架构以使我们的网上商店中的搜索更好地工作方面遇到了一些困难。

首先进行一些配置(Solr 4.2.1)

<field name="mfgpartno" type="text_en_splitting_tight" indexed="true" stored="true" />
<field name="mfgpartno_sort" type="string" indexed="true" stored="false" />
<field name="mfgpartno_search" type="sku_partial" indexed="true" stored="true" />

<copyField source="mfgpartno" dest="mfgpartno_sort" />
<copyField source="mfgpartno" dest="mfgpartno_search" />

<fieldType name="sku_partial" class="solr.TextField" omitTermFreqAndPositions="true">
    <analyzer type="index">
        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
        <filter class="solr.WordDelimiterFilterFactory" preserveOriginal="1" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="1" splitOnCaseChange="1"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.TrimFilterFactory" />
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="false"/>
        <filter class="solr.NGramFilterFactory" minGramSize="4" maxGramSize="100" side="front" />
        <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
    </analyzer>
    <analyzer type="query">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.TrimFilterFactory" />
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="false"/>
    </analyzer>
</fieldType>

让我把它分解成几个阶段(我只是要深入到足以复制这个问题 - 初始阶段不使用 edismax,这是我们选择在我们的网站上使用的):

  1. q=DV\-5PBRP <- 使用此查询我得到 18 个结果,但不是我要查找的结果(这很可能是对产品名称字段上的默认 df 搜索进行的 - 很好)
  2. q=mfgpartno_search:DV\-5PBRP <- 这给了我正在寻找的 1 个结果,但由于我需要在网站上进行查询构建,如果我可以使用 q 参数会更好像第 1 阶段。
  3. q=DV\-5PBRP&defType=edismax&qf=mfgpartno_search <- 这也给了我正在寻找的 1 个结果,但同样由于网站搜索 qf 需要跨越更多字段。因为它需要搜索更多字段(实际 qf = productname_search shortdesc_search fulldesc_search mfgpartno_search productname shortdesc fulldesc keywords)以获得更准确的搜索,所以我实现了阶段 4.
  4. q=DV\-5PBRP&defType=edismax&qf=mfgpartno_search&q.op=AND <- 通过这个测试我得到了 0 个结果 - 虽然这对我们网站上的大多数搜索都非常有效。

我在搜索时遇到的最大问题是破折号等特殊字符,有时必须是字面意思,有时又充当产品名称或描述中的分隔符。有时人们甚至会在部件号搜索中搜索破折号或将破折号替换为 space,它仍应显示相关数据。

我有点困惑如何让这个特殊字符搜索工作 - 特别是因为它与这个 mfgpartno_search 字段有关。我如何配置架构或查询(或两者)才能使其正常工作?

也许你可以试试Regular Expression Pattern Tokenizer,为你的文章编号制作一个合适的正则表达式。 Lucene(Solr 的基础)非常专注于散文的标记化。

这里你想要的可能是N-gram拆分,还有1-gram?也许破折号被空格替换了,比如

DV-5PBRP -> {DV 5PBRP、DV、5P、BR、PB、RP、D、V、5、P、B、R}

如您所见,对于非常小的字段,索引将非常大。确保结果的排名对于较大的 ngram 具有很大的权重。

我认为您应该删除文章编号字段的停用词列表。

N-gram 大小应该从 1 或 2 开始。

只需确保各种分析器不会:

  • 吞下破折号
  • 删除单个或几个字符(这些通常在停用词列表中)
  • 删除数字

如果您使用 HTTP get 方法,请对其进行编码并使用

发送
URLEncoder.encode(searchWord,"UTF-8")

这是java的情况。如果您不使用 java 尝试相应的编码代码。这将帮助我们避免"space"、“/”之类的问题

好的,我认为这个问题是想多了。

我曾假设(根据我的配置)示例部件号可能会像这样编入索引:

DV-5PBRP -> {DV 5PBRP, DV5PBRP, DV-5PBRP} + NGrams

我还假设在 "DV-5PBRP"(文字破折号)上进行搜索会匹配第三个选项(在我的问题中使用类似 #4 的查询)。

昨天我再次被同一个用户提醒这个问题,我开始考虑让我们尝试删除搜索中的分隔符。所以现在搜索变成了:

q=DV5PBRP&defType=edismax&qf=mfgpartno_search&q.op=AND

我得到了我想要的结果,这意味着我的 solr 配置至少给我一个像第二个索引选项一样的索引。

现在,在将搜索提交给 SOLR 之前,我已经开始从用户输入中删除分隔符。这似乎工作得很好!