Azure 认知搜索 - 如何按包含特殊字符的字段进行筛选

Azure Cognitive Search - How to filter by fields containing special characters

我们正在使用 Azure 认知搜索 .NET SDK 并尝试 $filter 可以包含 & 等搜索特殊字符以及单引号的字符串字段。

当使用特殊字符的厨房水槽过滤测试用例时,我们得到零结果(我们排除了 | 因为它是 search.in 的分隔符):

{
  "FirmName": "Crazy Charz Inc. ' + - && ! ( ) { } [ ] ^ \" ~ * ? : \ /"
  ...
}

当我们将带有 \ 的特殊字符转义为 and recommended here, and the single quote by double-quoting it '' (as revealed ,而不是在 SDK 文档中)时,我们得到零结果。

Filter in our SearchParameters object设置为:

search.in(FirmName, 'Crazy Charz Inc. '' \+ \- \&\& \! \( \) \{ \} \[ \] \^ \" \~ \* \? \: \ \/', '|')

(这是在 VS 中检查变量时的样子;它应该被正确转义。)

我们得到零结果。

我们已经确认它是特定于特殊字符的,因为我们有大量的相同字段匹配其他文档的测试,这些文档的值中不包含此类字符。

出于好奇,我们在搜索浏览器中尝试 运行 如下:

$filter=search.in(FirmName, 'Crazy Charz Inc. '' \+ \- \&\& \! \( \) \{ \} \[ \] \^ \" \~ \* \? \: \ \/', '|')

当我们这样做时,我们得到错误:

"Invalid expression: Found an unbalanced bracket expression.\r\nParameter name: $filter"

我们已经确认 SDK returns 是一个实际的零结果响应,而不是错误(我们在过滤器表达式中放置了一个实际的不平衡表达式以确认这一点)。

我们如何使用 .NET SDK $filter 处理带有特殊字符的值?这是一个错误,还是我们做错了什么?

注意:我们提供了一个选择列表并进行了精确匹配;因此过滤,而不是搜索,这个用例。我们稍后会添加对其他字段的搜索。

我们需要简单地对所有字段进行 URLEncode 吗?呃...

问题是您使用的编码方案与您想要的语法不同。

Azure 认知搜索中有三种查询语法,每种都有自己的编码规则:

  1. 简单的查询语法(在 search 参数中使用;您链接到的文档中描述的编码规则)
  2. 完整的 Lucene 查询语法(也用于 search,或多或少是简单查询语法的超集)
  3. OData 语法(在 $filter$select$orderby 中使用;记录在 here 中)。

双单引号规则来自OData。您应用的其他规则适用于简单查询语法,而不适用于 OData。

我编写了一个小型控制台应用程序来对此进行测试,并且我能够使用这个确切的字符串文字来匹配预期的文档:

@"search.in(hotelName, 'Crazy Charz Inc. '' + - && ! ( ) { } [ ] ^ "" ~ * ? : \ /', '|')"

请注意,因为我使用的是逐字字符串,所以只需要转义引号(OData 为单引号,编译器为双引号)。