【问题标题】:AzureSearch edgeNGram search matching too many documentsAzureSearch edgeNGram 搜索匹配太多文档
【发布时间】:2021-07-01 12:25:19
【问题描述】:

我正在尝试使用边缘 ngram 分析器分析的字段来实现前缀搜索。 但是,每当我进行搜索时,它都会返回类似的匹配项,但不包含搜索项。

以下查询

POST /indexes/resources/docs/search?api-version=2020-06-30

{
"queryType": "full",
"searchMode": "all",
"search": "short_text_prefix:7024032"
}

返回

{
"@odata.context": ".../indexes('resources')/$metadata#docs(*)",
"@search.nextPageParameters": {
    "queryType": "full",
    "searchMode": "all",
    "search": "short_text_prefix:7024032",
    "skip": 50
},
"value": [
    {
    "@search.score": 4.669537,
    "short_text_prefix": "7024032   "
    },
    {
    "@search.score": 4.6333756,
    "short_text_prefix": "7024030   "
    },
    {
    "@search.score": 4.6333756,
    "short_text_prefix": "7024034   "
    },
    {
    "@search.score": 4.6333756,
    "short_text_prefix": "7024031   "
    },
    {
    "@search.score": 4.6319494,
    "short_text_prefix": "7024033   "
    },
    ... omitted for brevity ...
],
"@odata.nextLink": ".../indexes('resources')/docs/search.post.search?api-version=2020-06-30"
}

其中包括一堆几乎与我的术语相符的文档。以及得分最高的“正确”文档。

自定义分析器像这样标记“7024032”

"@odata.context": "/$metadata#Microsoft.Azure.Search.V2020_06_30.AnalyzeResult",
"tokens": [
    {
    "token": "7",
    "startOffset": 0,
    "endOffset": 7,
    "position": 0
    },
    {
    "token": "70",
    "startOffset": 0,
    "endOffset": 7,
    "position": 0
    },
    {
    "token": "702",
    "startOffset": 0,
    "endOffset": 7,
    "position": 0
    },
    {
    "token": "7024",
    "startOffset": 0,
    "endOffset": 7,
    "position": 0
    },
    {
    "token": "70240",
    "startOffset": 0,
    "endOffset": 7,
    "position": 0
    },
    {
    "token": "702403",
    "startOffset": 0,
    "endOffset": 7,
    "position": 0
    },
    {
    "token": "7024032",
    "startOffset": 0,
    "endOffset": 7,
    "position": 0
    }
]
}

如何排除与词条不完全匹配的文档?

【问题讨论】:

    标签: azure azure-cognitive-search n-gram


    【解决方案1】:

    在这种情况下,Ngram 不是正确的方法,因为前缀“702403”出现在所有这些文档中。如果您将最小长度指定为要搜索的术语的长度,则可以使用它。

    这是一个例子:

    令牌长度:3

    示例内容:

    234

    1234

    2345

    3456

    001234

    99234345

    正在搜索“234”

    它将返回项目 1 (234)、2 (1234)、3 (2345)、4 (001234) 和 5 (99234345)

    另一种选择,如果你 100% 以你呈现的方式存储内容,你可以使用正则表达式来检索你想要的方式:

    /.*7024032\s+/

    【讨论】:

    • 不确定我是否关注。 “7024032”(我的搜索词)仅出现在其中一个文档中。结果中的第一名。我的搜索词是“short_text_prefix:7024032”。我猜这意味着它试图在令牌列表“7”、“70”、“702”、“7024”、“7024032”、“70240”、“702403”、“7024032”中找到令牌“7024032”。第二个文档将包含“7”、“70”、“702”、“7024”、“7024032”、“70240”、“702403”、“7024030”(最后一个标记不同)并且不应该匹配查询是我的理解。我认为正则表达式匹配对于我们的数据量来说不够高效。
    • 要清楚我正在尝试在字段 short_text_prefix 上实现有效的前缀匹配
    • 关于您的第一条评论,恰恰相反。子令牌也存在于其他文档中,这就是它们被检索的原因。您尝试检索的文档包含所有标记,这就是首先检索它的原因(或者在搜索词中,更相关)。
    • 查看我自己的答案。分离 indexAnalyzer 和 searchAnalyzer 是要走的路。并非所有文档中都存在完整的 7024032-token。但在搜索时,它被拆分为 ngram,匹配所有包含相同第一个字符的文档。
    【解决方案2】:

    我发现了问题:

    我使用“analyzer”属性创建了该字段,该属性引用了我的自定义分析器(“edge_nGram_analyzer”)。设置此字段意味着字符串在索引和搜索时都被标记化。所以搜索“7024032”意味着我正在搜索所有标记,根据 egde n-gram 分析器拆分:“7”、“70”、“702”、“7024”、“7024032”、“70240”、“702403” ", "7024032"

    可以改为使用 indexAnalyzer 和 searchAnalyzer 属性,将索引标记化与搜索标记化分开处理。当我单独使用它们时:

    { "indexAnalyzer": "edge_nGram_analyzer", "searchAnalyzer": "whitespace" }
    

    一切都按预期进行。

    【讨论】:

    • 很好地解释了分析仪不同字段属性之间的差异。非常有帮助。我一直在努力解决 AnalyzerName、SearchAnalyzerName 和 IndexAnalyzerName 之间的区别。
    猜你喜欢
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    相关资源
    最近更新 更多