【问题标题】:Solr: Wildcards and Case sensitivity searchSolr:通配符和区分大小写搜索
【发布时间】:2017-10-25 18:22:49
【问题描述】:

我一直在环顾四周,试图弄清楚这里发生了什么,但到目前为止都是空的。我希望有人可以指导我在哪里寻找解决方案。我有一个这样定义的文本字段:

<fieldType name="text" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <!-- in this example, we will only use synonyms at query time
    <filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
    -->
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="stopwords.txt"
            />
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="0"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt"/>
    <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="stopwords.txt"
            />
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt"/>
    <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
  </analyzer>
</fieldType>

我有一些记录具有以下键/值

"text":[
  "NOFX_SiteTest_4",
  "NOFX_SiteTest_4\nNOFX_SiteTest_4\n Fourteen\n Ten\n Thirteen\n Fifteen\n Two\n 3\n Select Fields"
]


"text":[
  "NOFX_SiteTest_44",
  "NOFX_SiteTest_44\nNOFX_SiteTest_44\n Fourteen\n Ten\n Thirteen\n Fifteen\n Two\n 3\n Select Fields"
]


"text":[
  "NOFX_SiteTest_445",
  "NOFX_SiteTest_445\nNOFX_SiteTest_445\n Fourteen\n Ten\n Thirteen\n Fifteen\n Two\n 3\n Select Fields"
]

我正在尝试各种搜索以让 Solr 返回这些记录。问题是,取决于我如何构建查询(基于我添加通配符的位置,如果我添加通配符,以及关于下划线的搜索文本的位置),我得到的结果是意外和不正确的。以下是我从 Solr Admin 查询页面运行的搜索:

SEARCH
text:(( NOFX_SiteTest_4* )) OR text_exact:(( NOFX_SiteTest_4* ))

RESULT
3 Records (correct)

SEARCH
text:(( NOFX_SiteTest_ )) OR text_exact:(( NOFX_SiteTest_ ))

RESULT
3 Records (correct)

SEARCH
text:(( NOFX_SiteTest )) OR text_exact:(( NOFX_SiteTest ))

RESULT
3 Records (correct)

SEARCH
text:(( NOFX_SiteTest* )) OR text_exact:(( NOFX_SiteTest* ))

RESULT
3 Records (correct)

SEARCH
text:(( nofx_sitetest_4 )) OR text_exact:(( nofx_sitetest_4 ))

RESULT
1 Record (correct)

SEARCH
text:(( nofx_sitetest_4* )) OR text_exact:(( nofx_sitetest_4* ))

RESULT
0 Records (incorrect)

SEARCH
text:(( nofx_sitetest_ )) OR text_exact:(( nofx_sitetest_ ))

RESULT
3 Records (correct)

SEARCH
text:(( nofx_sitetest* )) OR text_exact:(( nofx_sitetest* ))

RESULT
0 Records (incorrect)

在我看来,根据该字段的配置,Solr 应该将这两个查询视为相同:

text:(( NOFX_SiteTest_4* )) OR text_exact:(( NOFX_SiteTest_4* ))

text:(( nofx_sitetest_4* )) OR text_exact:(( nofx_sitetest_4* ))

为什么第一次搜索,字母正确大写,返回适当数量的记录,但第二次搜索,全部小写,它们不是。然而,在运行这些查询时:

text:(( NOFX_SiteTest_ )) OR text_exact:(( NOFX_SiteTest_ ))

text:(( nofx_sitetest_ )) OR text_exact:(( nofx_sitetest_ ))

返回正确数量的记录。为什么包含通配符会导致问题?特别是当搜索完全由小写字母组成时?

我希望有人能指出我正确的方向。我一直在查看文档并搜索类似的问题,但我遇到的任何问题似乎都无法帮助我解决问题或帮助我理解为什么会发生这种情况。

编辑:一些附加信息。

这是我在上面的搜索中使用的两个字段的定义:

<field name="text"       type="text"       indexed="true"  stored="true"  multiValued="true"/>
<field name="text_exact" type="text_exact" indexed="false"  stored="false" multiValued="true"/>

<!-- copy all fields to the default search field -->
<copyField source="title"   dest="text"/>
<copyField source="content" dest="text"/>
<copyField source="Comment" dest="text"/>

<!-- copy all fields to the exact match search field -->
<copyField source="title"   dest="text_exact"/>
<copyField source="content" dest="text_exact"/>
<copyField source="Comment" dest="text_exact"/>

texttext_exact 之间的唯一区别是字段类型的定义方式。当我的搜索是

text:(( NOFX_SiteTest_4* )) OR text_exact:(( NOFX_SiteTest_4* ))

它会找到 3 条记录(正如我在上面所说的),但它这样做是因为 text_exact 字段,而不是 text 字段。我觉得这很奇怪。运行搜索

text_exact:(( NOFX_SiteTest_4* ))

返回 3 条记录但运行搜索

text:(( NOFX_SiteTest_4* ))

返回 0 条记录。我可以看到为什么 text_exact 返回数据。因为在 text_exact 字段中有确切的文本。但我不确定为什么对text 的搜索不会产生任何记录。那个领域不应该更加开放和宽容吗?并且更允许通配符搜索?因为如果我删除星号,它确实会返回该确切文本位于 text 字段中的一条记录。为什么不将星号视为通配符?

最后,如果我删除通配符并将文本更改为全部小写,则在搜索text 字段时,它会轻松找到该记录。因此,无论问题是什么,它似乎都与使用星号作为通配符有关。

【问题讨论】:

    标签: search solr lucene


    【解决方案1】:

    首先是LowerCaseFilterFactory过滤器,应该放在WordDelimiterFilterFactory过滤器之前

    <filter class="solr.LowerCaseFilterFactory"/>
    

    它将所有字符转换为小写,然后通过wordDelimiterFilter进行分割

    当您使用通配符时,添加额外的 text:(( NOFX_SiteTest_4 )),这将是精确的数学运算。

    决赛

    text:( NOFX_SiteTest_4* ) OR text_exact:( NOFX_SiteTest_4*) OR text:( NOFX_SiteTest_4 )
    

    请使用分析 solr 工具查看发生了什么。

    【讨论】:

    • Solr 分析工具并没有告诉我太多信息。我想我有很多东西要学习如何阅读它。我在我的架构中移动了过滤器,并按照您的建议添加了额外的文本:字段查询,但这并没有改变任何东西。小写查询仍然没有产生任何文档。
    • 可以给我们看看您的打印屏幕吗? lucene.apache.org/solr/guide/6_6/analysis-screen.html
    • 我的原始查询:imgur.com/a/IPO7N。您建议的查询:imgur.com/a/g2fx0。这对我来说仍然是希腊语。我现在正在阅读分析工具。
    • nvm,我现在明白这意味着什么......但是,我对它的理解还不够,无法确定为什么我的查询没有返回任何记录。甚至是你上面建议的那个......
    • @Christoph 您在索引和查询中有两种不同的 WordDelimiterFilterFactory 设置。只需将 nofx_sitetest_4* 添加到 fieldValue 并比较索引之间的查询。分析工具可帮助您了解 solr 如何拆分文本。在您的情况下,当有人搜索您 catenateWords = 0 时,nofx_sitetest 变为 nofx , sitetest 然后您将其与索引进行比较,但索引使用catenateWords = 0
    【解决方案2】:

    当您使用通配符时,分析链不会像往常一样运行。

    唯一的过滤器invoked are those that implement MultiTermAwareComponent,因此分析页面不会很好地告诉您那里发生了什么。

    这意味着当您进行通配符搜索时,如果索引管道已更改令牌(拆分它们等),则该处理将不会发生查询时。这可能就是为什么你没有得到你想要的命中,但是没有通配符它可以工作。这里的原因是 WordDelimiterFilter 不是 multitermaware,因此当您编制索引时,输入文本被分成多个标记,而当您查询时,这不会发生。由于令牌不匹配(我敢打赌,只有 NOFX* 可能匹配,因为这将是双方的单个令牌),您不会受到打击。

    如果您确实需要对分析的文本进行通配符匹配,那么您可能必须改为使用 NgramFilter,然后调整该过滤器以获得每个标记所需的结果。但这将再次表现不同,具体取决于您在链中添加 NgramFilter 的位置(即在单词分隔符之前或之后等)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      相关资源
      最近更新 更多