将 Solr 4.10 升级到 6.3 后,搜索停止工作

After upgrading Solr 4.10 to 6.3 the search stopped working

我有一项升级 Solr 的任务,但之前从未使用过 Solr。 目前我有下一个堆栈:Django 1.9.12 + Oscar 1.3 + Solr 6.3.0 + Haystack 2.5.1

我有一个由 Haystack 生成的模式,将其放在 managed-schema 文件中并根据 Whosebug 的答案进行了一些修改,因为 Solr 不想开始。 现在我有 Solr 可以启动,但无法通过网站的搜索字段找到任何东西(howower 使用 Solr 4.10,搜索按预期工作,没有任何问题)。

在以下部分的 solrconfig.xml 中:

<requestHandler name="/select" class="solr.SearchHandler">
<!-- default values for query parameters can be specified, these
     will be overridden by parameters in the request
  -->
<lst name="defaults">
  <str name="echoParams">explicit</str>
  <int name="rows">10</int>
</lst>

我尝试添加:

<str name="df">text</str>
<str name="q.op">AND</str>

之后搜索部分开始工作。

几个例子:

  1. 有这样的项目INTEL Pentium G3260 (CM8064601482506),搜索只用INTEL PentiumCM8064601482506。如果我想查找 INTEL Pentium G3260Pentium G3260INTEL G3260G3260 - 没有结果。

  2. Search string: AMD a8-6500; Result: 没有显示(无结果)-> 应该找到 AMD a8-6500

  3. Search string:AMD; Result: 显示所有 AMD 产品 -> 符合预期

如果我将 <str name="q.op">AND</str> 更改为 <str name="q.op">OR</str>:

  1. Search string: AMD a8-6500; Result: AMD A8-6500 显示所有 AMD 和 A8-6500 -> 应该只找到 AMD a8-6500

  2. Search string:a8-6500; Result: AMD A8-6500 (AD650BOKA44HL) 和 INTEL Core™ i5 6500 -> 应该只找到 AMD a8-6500

我目前的 solrconfig.xml and managed-schema 在 GitHub。

作为我目前使用的索引字段EdgeNgramField,即:

from haystack import indexes

class ProductIndexes(indexes.SearchIndex, indexes.Indexable):
    text = indexes.EdgeNgramField(
            document=True, use_template=True,
            template_name='search/indexes/cpu/item_text.txt')

如何fix\normalize搜索?


更新 1: 仪表板日志页面的警告

[default] default search field in schema is text. WARNING: Deprecated,&#8203; please use 'df' on request instead.
[default] query parser default operator is AND. WARNING: Deprecated,&#8203; please use 'q.op' on request instead.

可以通过移除

来修复
  <defaultSearchField>text</defaultSearchField>
  <solrQueryParser defaultOperator="AND"/>

来自 managed-schema 个文件

更新二: 根据苏格拉底的回答,这里是最后的变化:

  1. indexes.EdgeNgramField 在接下来的代码中:

    class ProductIndexes(indexes.SearchIndex, indexes.Indexable): text = indexes.EdgeNgramField( document=True, use_template=True, template_name='search/indexes/cpu/item_text.txt')

    改为indexes.CharField.

  2. 因为我有其他字段 indexes.CharField,在 managed-schema 中我发现,这些字段使用类型 text_en,并将 fieldType name="text_en" 替换为:

<fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <!-- in this example, we will only use synonyms at query time
    <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
    -->
    <!-- Case insensitive stop word removal.
    -->
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="lang/stopwords_en.txt"
        />
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.EnglishPossessiveFilterFactory"/>
    <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
    <!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
    <filter class="solr.EnglishMinimalStemFilterFactory"/>
      -->
    <filter class="solr.PorterStemFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="lang/stopwords_en.txt"
    />
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.EnglishPossessiveFilterFactory"/>
    <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
    <!-- Optionally you may want to use this less aggressive stemmer instead of PorterStemFilterFactory:
    <filter class="solr.EnglishMinimalStemFilterFactory"/>
      -->
    <filter class="solr.PorterStemFilterFactory"/>
  </analyzer>
</fieldType>

haystack生成,至:

<fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
    <analyzer type="index">
      <tokenizer class="solr.StandardTokenizerFactory"/>
      <filter class="solr.StandardFilterFactory"/>
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
    <analyzer type="query">
      <tokenizer class="solr.StandardTokenizerFactory"/>
      <filter class="solr.StandardFilterFactory"/>
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
</fieldType>

  1. sorlconfig.xml代码中:

<requestHandler name="/select" class="solr.SearchHandler">
  <lst name="defaults">
    <str name="echoParams">explicit</str>
    <int name="rows">10</int>
  </lst>
</requestHandler>

更改为:

<requestHandler name="/select" class="solr.SearchHandler">
    <lst name="defaults">
      <str name="echoParams">explicit</str>
      <int name="rows">10</int>
      <str name="df">text</str>
      <str name="q.op">AND</str>
    </lst>
</requestHandler>

当你在 solr 请求中使用 q.op 时。 "q.op" 请求参数优先于此。

<solrQueryParser defaultOperator="OR"/>

带有 q.op 参数的示例查询:

http://localhost:8983/solr/collection1/select?indent=on&q.op=AND&q=for ipod&wt=json

If I want to find INTEL Pentium G3260 or Pentium G3260 or INTEL G3260 or G3260 - no results.

这与字段的分析和标记化方式有关。请参阅文档 here

使用 ClassicTokenizerFactory 的标记化将表现如下: 输入:"Please, email john.doe@foo.com by 03-09, re: m37-xq." 输出:"Please"、"email"、"john.doe@foo.com"、"by"、“03-09”、"re"、"m37-xq"

使用 solr.EdgeNGramTokenizerFactory 的标记化将表现如下: 输入:"babaloo" 输出:"ba"、"bab"、"baba"、"babal"

在 schema.xml 中,您可以定义一个新的字段类型,或者像这样更新现有的字段类型:

<fieldType name="text" class="solr.TextField">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StandardFilterFactory"/>
  </analyzer>
</fieldType>

试一试,看看哪一个适合您的场景。您可能还想看看您给出的查询是如何规范化的。但这是一个很好的起点。