【问题标题】:Noise / stop words in the search query removes correct search results搜索查询中的噪音/停用词会删除正确的搜索结果
【发布时间】:2021-12-26 15:33:02
【问题描述】:

我们有不同语言的文件。为了能够搜索不同语言的文档,我们创建了一个索引,每种语言都有一个字段。我们确保根据文档的语言填写适用的字段。 (其他字段为空)我们不知道搜索的是哪种语言,因此我们确保搜索所有字段,因此始终搜索适用的字段。

当用户提供包含干扰词/停用词的搜索查询时,我们遇到了问题。当我们使用 searchMode=all 并使用语言分析器时,它似乎从结果集中删除了完全有效的搜索结果。 例如,我们在索引中有以下文本来测试这种行为: 名称中带有 和 it 的文档标题

当我们使用以下搜索查询时,我们会得到预期的搜索结果: search=文档标题名称&QueryType=full&searchMode=all&$count=true

但是,当我们尝试搜索确切的标题(或者甚至添加一些干扰词,例如 with、the 和 in)时,使用 en.microsoft 分析器时不会返回结果。当我们使用另一种语言分析器(使用其他噪音/停用词)时,将返回结果。 我们在使用荷兰语索引时使用 nl.microsoft 分析器得到了类似的结果,并尝试搜索还包含荷兰语噪音/停用词(如“bij”、“in”或“en”)的文本,而这是索引文本的一部分。

有没有办法解决这个问题?使用语言分析器时,这是搜索中的错误吗? 我假设如果我们创建一个搜索查询来搜索过滤噪音/停用词的索引,那么在执行搜索查询之前,认知搜索也会从查询中删除噪音/停用词。

注意:我们还发现了以下 stackoverflow 帖子: Queries with stopwords and searchMode=all return no results 似乎仅当我们使用不同语言搜索多个字段时才会出现此问题。我可以确认这一点。如果我只使用以下查询搜索英文字段来测试搜索查询,我们会得到预期的结果: search=文档标题名称&QueryType=full&searchMode=all&searchFields=Title_enus&$count=true

但是,当我尝试搜索使用英语和荷兰语的两个字段时,我不再得到英语结果: search=文档标题名称&QueryType=full&searchMode=all&searchFields=Title_enus,Title_nlnl&$count=true

我们的实际情况与本文略有不同,因为我们使用 OR 子句在多个字段中进行搜索。如果我进行更多测试并可以提供准确的测试查询(包括其结果),我会更新这篇文章。

【问题讨论】:

  • 您能否提供一些最小样本记录、您使用的查询和预期结果?不清楚你的意思。您说您的实际情况不同,并且您使用 OR 查询。您发布的查询使用 AND(隐式)。我认为您的链接文章stackoverflow.com/questions/43671272/… 解释得很好。

标签: azure-cognitive-search


【解决方案1】:

使用 OR 查询即可。您也可以使用任何搜索模式。据我了解,您的内容是多语言的,每条记录有多种语言。

索引

    "fields": [
    {"name": "Id", "type": "Edm.String", "searchable": false, "key": true, "indexAnalyzer": null, "searchAnalyzer": null, "analyzer": null, "synonymMaps": [] }, 
    {"name": "Title_enus", "type": "Edm.String", "searchable": true, "analyzer":"en.microsoft"}, 
    {"name": "Title_nlnl", "type": "Edm.String", "searchable": true, "analyzer":"nl.microsoft"}],  

内容

使用您链接到的文章中的示例内容以及您的索引定义。

    "value": [
    {
        "@search.action": "mergeOrUpload",
        "Id": "1",
        "Title_enus": "Waiting for a bus",
        "Title_nlnl": "Wachten op een bus"
    },
    {
        "@search.action": "mergeOrUpload",
        "Id": "2",
        "Title_enus": "Run to the hills",
        "Title_nlnl": "Ren naar de heuvels"
    }
]

您不知道最终用户输入的语言是什么。无论输入是什么,您都将其插入到您准备好的查询中。考虑以下示例

  1. search=wait for&$count=true&searchMode=all&queryType=full
  2. search=wait for&$count=true&searchMode=all&queryType=full&searchFields=Title_enus
  3. search=wait for&$count=true&searchMode=all&queryType=full&searchFields=Title_enus,Title_nlnl
  4. search=Title_enus:"等待" OR Title_nlnl:"等待"&$count=true&searchMode=all&queryType=full
  5. search=wait for&$count=true&searchMode=any&queryType=full

在场景 1 中,您搜索两个搜索属性。并且所有模式都规定您的条件 wait for 必须同时存在。由于 Title_nlnl 属性中不存在,所以不匹配

在场景 2 中,我指定我只想在 Title_enus 属性内进行搜索。这 匹配,因为 wait 匹配。 for 是一个停用词,因此被忽略。我知道这种方案不适合您,因为您希望用户能够在所有内容中以所有语言进行搜索。不过,它有助于我们理解。

在场景 3 中,我们要同时搜索 Title_enusTitle_nlnl。这实际上与场景 1 相同。对于要匹配的记录,搜索词必须同时匹配 Title_enus AND Title_nlnl。 Title_nlnl 中没有 wait for (注意 for 没有作为停用词去掉,但也没关系)。

在场景 4 中,我们使用实际的 OR 查询。您接受用户的输入,并且您的要求是它必须匹配 Title_enusTitle_nlnl。在这里,您得到了记录 1 作为匹配项,正如预期的那样。

        "Id": "1",
        "Title_enus": "Waiting for a bus",
        "Title_nlnl": "Wachten op een bus"

在场景 5中,我们使用任意模式。这将使搜索语法更简单,并且返回与场景 4 相同的结果。

【讨论】:

  • 在我们的索引中,根据源文档的语言,仅填写了一个字段。在我们的搜索查询中,我们使用 OR 来搜索所有字段。我认为情景 4 产生了预期的结果。在我们最初的场景中,我们将搜索查询“a bus”分解为以下搜索查询:search=(Title_enus:"a" OR Title_nlnl:"a")AND(Title_enus:"bus" OR Title_nlnl:"bus")&$ count=true&queryType=full 这不会为包含英文文本“waiting for a bus”的文档产生结果,因为“a”是一个停止/噪音词,并且在搜索时显然总是解析为 false)
猜你喜欢
  • 2010-11-18
  • 1970-01-01
  • 2018-08-03
  • 2019-05-12
  • 2015-11-11
  • 2014-11-25
  • 1970-01-01
  • 1970-01-01
  • 2013-10-07
相关资源
最近更新 更多