处理 Azure 认知搜索中的单数和复数搜索词
Handle singular and plural search terms in Azure Cognitive Search
我们使用 Azure 认知搜索作为搜索图像的搜索引擎。分析器是 Lucene 标准,当用户搜索“苏格兰风景”时,我们的一些用户声称他们的图像丢失了。然后,他们必须在图片中添加关键字“风景”,以便搜索引擎可以找到它们。
将分析器更改为“en-lucene”或“en-microsoft”似乎只会产生更小的搜索结果,我们的用户不喜欢这样。
Azure 认知搜索似乎不区分单复数词。为了解决这个问题,我在数据库中创建了一个字典,使用了词形变化并尝试操纵搜索词:
foreach (var term in terms)
{
if (ps.IsSingular(term))
{
// check with db
var singular = noun.GetSingularWord(term);
if (!string.IsNullOrEmpty(singular))
{
var plural = ps.Pluralize(term);
keywords = keywords + " " + plural;
}
}
else
{
// check with db
var plural = noun.GetPluralWord(term);
if (!string.IsNullOrEmpty(plural))
{
var singular = ps.Singularize(term);
keywords = keywords + " " + singular;
}
}
}
我的解决方案不是 100% 理想,但如果 Azure 认知搜索能够区分单复数词就更好了。
更新:
自定义分析器可能是我问题的答案,我只需要找到正确的标记过滤器。
更新:
下面是我的自定义分析器。它删除 html 结构、撇号、停用词并将它们转换为小写。分词器是 MicrosoftLanguageStemmingTokenizer,它将单词缩减为其词根,因此它适用于复数到单数的场景(搜索“landscapes”returns“landscapes”和“landscape”)
"analyzers": [
{
"name": "p4m_custom_analyzer",
"@odata.type": "#Microsoft.Azure.Search.CustomAnalyzer",
"charFilters": [
"html_strip",
"remove_apostrophe"
],
"tokenizer": "custom_tokenizer",
"tokenFilters": [
"lowercase",
"remove_stopwords"
]
}
],
"charFilters": [
{
"name": "remove_apostrophe",
"@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
"mappings": ["'=>"]
}
],
"tokenizers": [
{
"name": "custom_tokenizer",
"@odata.type":"#Microsoft.Azure.Search.MicrosoftLanguageStemmingTokenizer",
"isSearchTokenizer": "false"
}
],
"tokenFilters": [
{
"name": "remove_stopwords",
"@odata.type": "#Microsoft.Azure.Search.StopwordsTokenFilter"
}
]
我还没有找到相反的方法。如果用户搜索“apple”,它应该 return“apple”和“apples”。
en.lucene 和 en.microsoft 都应该对此有所帮助,您不需要手动扩展您这边的词形变化。我很惊讶听到你看到他们更少回忆。一般来说,我希望这些比标准分析仪有更高的召回率。您是否有机会使用不同的分析器拥有多个可搜索字段?那可能会干扰。否则,很高兴看到一个特定的案例(query/document 对以及索引定义)来进一步调查。
作为快速测试,我使用了这个小型索引定义:
{
"name": "inflections",
"fields": [
{
"name": "id",
"type": "Edm.String",
"searchable": false,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": false,
"key": true
},
{
"name": "en_ms",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"sortable": false,
"facetable": false,
"key": false,
"analyzer": "en.microsoft"
}
]
}
这些文档:
{
"id": "1",
"en_ms": "example with scottish landscape as part of the sentence"
},
{
"id": "2",
"en_ms": "this doc has one apple word"
},
{
"id": "3",
"en_ms": "this doc has two apples in it"
}
对于这次搜索 search=landscapes
我看到了这些结果:
{
"value": [
{
"@search.score": 0.9631388,
"id": "1",
"en_ms": "example with scottish landscape as part of the sentence"
}
]
}
对于 search=apple
我看到:
{
"value": [
{
"@search.score": 0.51188517,
"id": "3",
"en_ms": "this doc has two apples in it"
},
{
"@search.score": 0.46152657,
"id": "2",
"en_ms": "this doc has one apple word"
}
]
}
我们使用 Azure 认知搜索作为搜索图像的搜索引擎。分析器是 Lucene 标准,当用户搜索“苏格兰风景”时,我们的一些用户声称他们的图像丢失了。然后,他们必须在图片中添加关键字“风景”,以便搜索引擎可以找到它们。
将分析器更改为“en-lucene”或“en-microsoft”似乎只会产生更小的搜索结果,我们的用户不喜欢这样。
Azure 认知搜索似乎不区分单复数词。为了解决这个问题,我在数据库中创建了一个字典,使用了词形变化并尝试操纵搜索词:
foreach (var term in terms)
{
if (ps.IsSingular(term))
{
// check with db
var singular = noun.GetSingularWord(term);
if (!string.IsNullOrEmpty(singular))
{
var plural = ps.Pluralize(term);
keywords = keywords + " " + plural;
}
}
else
{
// check with db
var plural = noun.GetPluralWord(term);
if (!string.IsNullOrEmpty(plural))
{
var singular = ps.Singularize(term);
keywords = keywords + " " + singular;
}
}
}
我的解决方案不是 100% 理想,但如果 Azure 认知搜索能够区分单复数词就更好了。
更新: 自定义分析器可能是我问题的答案,我只需要找到正确的标记过滤器。
更新: 下面是我的自定义分析器。它删除 html 结构、撇号、停用词并将它们转换为小写。分词器是 MicrosoftLanguageStemmingTokenizer,它将单词缩减为其词根,因此它适用于复数到单数的场景(搜索“landscapes”returns“landscapes”和“landscape”)
"analyzers": [
{
"name": "p4m_custom_analyzer",
"@odata.type": "#Microsoft.Azure.Search.CustomAnalyzer",
"charFilters": [
"html_strip",
"remove_apostrophe"
],
"tokenizer": "custom_tokenizer",
"tokenFilters": [
"lowercase",
"remove_stopwords"
]
}
],
"charFilters": [
{
"name": "remove_apostrophe",
"@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
"mappings": ["'=>"]
}
],
"tokenizers": [
{
"name": "custom_tokenizer",
"@odata.type":"#Microsoft.Azure.Search.MicrosoftLanguageStemmingTokenizer",
"isSearchTokenizer": "false"
}
],
"tokenFilters": [
{
"name": "remove_stopwords",
"@odata.type": "#Microsoft.Azure.Search.StopwordsTokenFilter"
}
]
我还没有找到相反的方法。如果用户搜索“apple”,它应该 return“apple”和“apples”。
en.lucene 和 en.microsoft 都应该对此有所帮助,您不需要手动扩展您这边的词形变化。我很惊讶听到你看到他们更少回忆。一般来说,我希望这些比标准分析仪有更高的召回率。您是否有机会使用不同的分析器拥有多个可搜索字段?那可能会干扰。否则,很高兴看到一个特定的案例(query/document 对以及索引定义)来进一步调查。
作为快速测试,我使用了这个小型索引定义:
{
"name": "inflections",
"fields": [
{
"name": "id",
"type": "Edm.String",
"searchable": false,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": false,
"key": true
},
{
"name": "en_ms",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"sortable": false,
"facetable": false,
"key": false,
"analyzer": "en.microsoft"
}
]
}
这些文档:
{
"id": "1",
"en_ms": "example with scottish landscape as part of the sentence"
},
{
"id": "2",
"en_ms": "this doc has one apple word"
},
{
"id": "3",
"en_ms": "this doc has two apples in it"
}
对于这次搜索 search=landscapes
我看到了这些结果:
{
"value": [
{
"@search.score": 0.9631388,
"id": "1",
"en_ms": "example with scottish landscape as part of the sentence"
}
]
}
对于 search=apple
我看到:
{
"value": [
{
"@search.score": 0.51188517,
"id": "3",
"en_ms": "this doc has two apples in it"
},
{
"@search.score": 0.46152657,
"id": "2",
"en_ms": "this doc has one apple word"
}
]
}