我有一个相当基本的 Azure 搜索索引,其中包含多个可搜索字符串数据字段,例如[删节]...
"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": []
}
]
Field1
加载字母数字 ID 数据,Field2
加载英语字符串数据,特别是记录的名称/标题。 searchMode=all
还用于确保结果的准确性。
假设索引的其中一条记录具有以下 Field2
数据:商业、组织行为和教练(荣誉)文学士
。将其放入 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
}
]
如您所见,返回的标记正是您对此类字符串的期望。但是,当使用相同的索引字符串值作为搜索词时(遗憾的是,在本例中是有效的用户案例),除非您显式使用 searchFields=Field2
,否则返回的结果将不符合预期。
查询 1(返回 0 个结果):
?searchMode=all&search=BA%20(Hons)%20in%20Business%2C%20Organisational%20Behaviour%20and%20Coaching
查询 2(返回 0 个结果):
?searchMode=all&searchFields=Field1,Field2&search=BA%20(Hons)%20in%20Business%2C%20Organisational%20Behaviour%20and%20Coaching
查询 3(按预期返回 1 个结果):
?searchMode=all&searchFields=Field2&search=BA%20(Hons)%20in%20Business%2C%20Organisational%20Behaviour%20and%20Coaching
那么为什么这只返回带有 searchFields=Field2
的预期结果,而不是未定义 searchFields
或 searchFields=Field1,Field2
的结果?我不希望 Field1
上的不匹配会排除 Field2
上明显匹配的结果?
此外,删除搜索词中的 "in"
和 "and"
似乎可以纠正问题并返回预期结果。例如:
查询 4(按预期返回 1 个结果):
?searchMode=all&search=BA%20(Hons)%20Business%2C%20Organisational%20Behaviour%20Coaching
(这几乎就像一个分析器正在对索引数据进行标记,而另一个完全不同的分析器正在对搜索词进行标记,尽管在考虑查询 3 时该理论没有任何意义,因为它使用完全相同的索引数据/搜索词。)
由于我完全没有想法并且在文档中找不到更多内容,有人能够阐明这里发生的情况吗?
注意。请记住,我希望了解为什么 Azure 搜索会以这种方式运行,而不一定需要解决方法。
最佳答案
您没有获得任何点击的原因是您使用 searchMode=all 时处理停用词的方式。searchMode=all。标准分析器不会删除停用词。 Lucene 和 Microsoft 英语分析器删除了停用词。我通过使用您的属性定义和示例数据创建索引来进行验证。如果您使用标准分析器,则不会删除停用词,并且在使用 searchMode=all 时您也会获得匹配项。要在使用 Lucene 或 Microsoft 分析器和简单查询模式时获得匹配,您必须使用短语搜索。
当您在示例中测试 en.microsoft 分析器时,您只能从分析器第一阶段的操作中获得响应。它将您的查询拆分为标记。在您的情况下,其中两个标记也是英语中的停用词(in、and)。停用词删除是词法分析的一部分,稍后在 stage 2 中完成。正如文章 Anatomy of a search request 中所述。此外,词法分析仅适用于“需要完整术语的查询类型”,例如searchMode=all。请参阅Exceptions to lexical analysis了解更多示例。
这里之前有一篇文章对此进行了更详细的解释。请参阅Queries with stopwords and searchMode=all return no results
我知道您没有要求解决方法,但为了更好地了解发生的情况,列出一些可能的解决方法可能会很有用。
- 对于英语分析器,请通过将查询括在引号中来使用短语搜索:search="BA (Hons) in Business, Organizational Behaviour and Coaching"&searchMode=all
- 标准分析器按照您期望的方式工作:search=商业、组织行为和教练(荣誉)文学士&searchMode=all
- 通过 defining a custom analyzer 禁用词法分析.
关于当没有定义或定义多个搜索字段时,Azure 搜索无法返回预期结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64357655/