未定义或多个搜索字段时,Azure 搜索无法返回预期结果

Jam*_*Law 5 lucene azure azure-cognitive-search

我有一个相当基本的 Azure 搜索索引,其中包含多个可搜索字符串数据的字段,例如 [abridged]...

"fields": [
  {
    "name": "Field1",
      "type": "Edm.String",
      "facetable": false,
      "filterable": true,
      "key": true,
      "retrievable": true,
      "searchable": true,
      "sortable": false,
      "analyzer": null,
      "indexAnalyzer": null,
      "searchAnalyzer": null,
      "synonymMaps": [],
      "fields": []
  },
  {
    "name": "Field2",
      "type": "Edm.String",
      "facetable": false,
      "filterable": true,
      "retrievable": true,
      "searchable": true,
      "sortable": false,
      "analyzer": "en.microsoft",
      "indexAnalyzer": null,
      "searchAnalyzer": null,
      "synonymMaps": [],
      "fields": []
  }
]
Run Code Online (Sandbox Code Playgroud)

Field1加载了字母数字 id 数据并Field2加载了英语字符串数据,特别是记录的名称/标题。searchMode=all还用于确保结果的准确性。

假设被索引的记录之一具有以下Field2数据:BA (Hons) in Business, Organisational Behaviour and Coaching. 将其放入en.microsoft分析器,这是我们得到的结果:

"tokens": [
    {
        "token": "ba",
        "startOffset": 0,
        "endOffset": 2,
        "position": 0
    },
    {
        "token": "hon",
        "startOffset": 4,
        "endOffset": 8,
        "position": 1
    },
    {
        "token": "hons",
        "startOffset": 4,
        "endOffset": 8,
        "position": 1
    },
    {
        "token": "business",
        "startOffset": 13,
        "endOffset": 21,
        "position": 3
    },
    {
        "token": "organizational",
        "startOffset": 23,
        "endOffset": 37,
        "position": 4
    },
    {
        "token": "organisational",
        "startOffset": 23,
        "endOffset": 37,
        "position": 4
    },
    {
        "token": "behavior",
        "startOffset": 38,
        "endOffset": 47,
        "position": 5
    },
    {
        "token": "behaviour",
        "startOffset": 38,
        "endOffset": 47,
        "position": 5
    },
    {
        "token": "coach",
        "startOffset": 52,
        "endOffset": 60,
        "position": 7
    },
    {
        "token": "coaching",
        "startOffset": 52,
        "endOffset": 60,
        "position": 7
    }
]
Run Code Online (Sandbox Code Playgroud)

如您所见,返回的标记正是您对此类字符串所期望的。但是,当涉及使用相同的索引字符串值作为搜索词时(可悲的是,在这种情况下是一个有效的用户案例),除非您明确使用searchFields=Field2.

查询 1(返回 0 个结果):

?searchMode=all&search=BA%20(Hons)%20in%20Business%2C%20Organisational%20Behaviour%20and%20Coaching
Run Code Online (Sandbox Code Playgroud)

查询 2(返回 0 个结果):

?searchMode=all&searchFields=Field1,Field2&search=BA%20(Hons)%20in%20Business%2C%20Organisational%20Behaviour%20and%20Coaching
Run Code Online (Sandbox Code Playgroud)

查询 3(按预期返回 1 个结果):

?searchMode=all&searchFields=Field2&search=BA%20(Hons)%20in%20Business%2C%20Organisational%20Behaviour%20and%20Coaching
Run Code Online (Sandbox Code Playgroud)

那么为什么这只会返回预期的结果,searchFields=Field2而不是没有searchFields定义或searchFields=Field1,Field2?我不希望不匹配Field1排除明显匹配的结果Field2

此外,删除搜索词中的"in""and"似乎可以更正问题并返回预期结果。例如:

查询 4(按预期返回 1 个结果):

?searchMode=all&search=BA%20(Hons)%20Business%2C%20Organisational%20Behaviour%20Coaching
Run Code Online (Sandbox Code Playgroud)

(这几乎就像一个分析器正在对索引数据进行标记,而一个完全不同的分析器正在对搜索词进行标记,尽管在考虑查询 3 时该理论没有任何意义,因为它使用完全相同的索引提供了正匹配数据/搜索词。)

有没有人能够阐明这里发生的事情,因为我完全没有想法并且在文档中找不到更多内容?

注意。请记住,我希望了解为什么 Azure 搜索会以这种方式运行,而不一定要解决这个问题。

dan*_*und 2

您没有获得任何点击的原因是您使用searchMode=all时如何处理停用词。标准分析器不会删除停用词。Lucene 和 Microsoft 英语分析器删除了停用词。我通过使用您的属性定义和示例数据创建索引来进行验证。如果您使用标准分析器,则不会删除停用词,并且在使用 searchMode=all 时您也会获得匹配项。要在使用 Lucene 或 Microsoft 分析器和简单查询模式时获得匹配,您必须使用短语搜索。

当您在示例中测试 en.microsoft 分析器时,您只能从分析器第一阶段的操作中获得响应。它将您的查询拆分为标记。在您的情况下,其中两个标记也是英语中的停用词(in、and)。停用词删除是词法分析的一部分,该分析稍后在第 2 阶段完成,如“搜索请求剖析”一文中所述。此外,词法分析仅适用于“需要完整术语的查询类型”,例如searchMode=all。有关更多示例,请参阅词法分析的例外。

之前有一篇文章对此进行了更详细的解释。请参阅带有停用词和 searchMode=all 的查询不返回任何结果

我知道您没有要求解决方法,但为了更好地了解发生的情况,列出一些可能的解决方法可能会很有用。

  • 对于英语分析器,通过将查询括在引号中来使用短语搜索:search="BA (Hons) in Business, Organizational Behaviour and Coaching"&searchMode=all
  • 标准分析器按照您期望的方式工作:search=商业、组织行为和教练(荣誉)文学士&searchMode=all
  • 通过定义自定义分析器来禁用词法分析。