Azure AI 搜索中的简单查询语法

对于全文搜索方案,Azure AI 搜索实现了两种基于 Lucene 的查询语言,每个对应一个查询分析器。 简单查询分析器是默认的。 它涵盖常见用例,并会尝试解释请求,即使请求未完全组合。 另一个分析器是 Lucene 查询分析器,它支持更高级的查询构造。

本文是简单查询分析器的查询语法参考。

这两个分析器的查询语法都适用于在查询请求search 参数中传递的查询表达式(不要与 OData 语法混淆),具有自己的语法和规则来处理同一请求中的 filterorderby 表达式。

尽管简单分析器基于 Apache Lucene 简单查询分析器类,但其在 Azure AI 搜索中的实现排除了模糊搜索。 如果需要模糊搜索,请考虑改用另一种可供选择的语法:完整 Lucene 查询语法

示例(简单语法)

此示例显示了一个简单的查询,该查询通过 "queryType": "simple" 和有效语法进行区分。 虽然下面设置了查询类型,但它是默认值,除非你是从替代类型中进行还原,否则可以省略它。 下面的示例是针对独立字词的搜索,要求所有匹配文档都包含“pool”。

POST https://{{service-name}}.search.azure.cn/indexes/hotel-rooms-sample/docs/search?api-version=2020-06-30
{
  "queryType": "simple",
  "search": "budget hotel +pool",
  "searchMode": "all"
}

searchMode 参数是在此示例中是相关的。 通常情况下,只要布尔运算符出现在查询中,就应设置 searchMode=all 以确保匹配所有条件。 否则,可以使用默认的 searchMode=any,以便更有利于提高召回率(与提高精准率相比)。

有关更多示例,请参阅简单查询语法示例。 有关查询请求和参数的详细信息,请参阅搜索文档 (REST API)

针对字词和短语的关键字搜索

传递给 search 参数的字符串可以包括任何受支持语言中的字词或短语、布尔运算符、优先级运算符、“开头为”查询的通配符或前缀字符、转义符和 URL 编码字符。 search 参数是可选的。 在未指定该参数的情况下,搜索(search=*search=" ")会以任意(未排名)顺序返回前 50 个文档。

  • 字词搜索是针对一个或多个字词的查询,其中的任何字词都被视为一个匹配项。

  • 短语搜索是指搜索用引号 引起来的精确短语。 例如,Roach Motel(没有引号)会以任何顺序在任何位置搜索包含 Roach 和/或 Motel 的文档,而 "Roach Motel"(带引号)则只会匹配包含整个短语并按该顺序排列的文档(词法分析仍然适用)。

    可能需要在短语搜索中对引号进行转义,具体取决于你的搜索客户端。 例如,在某个 POST 请求的 Postman 中,请求正文中针对 "Roach Motel" 的短语搜索应指定为 "\"Roach Motel\""

默认情况下,在 search 参数中传递的所有字符串都会进行词法分析。 请务必了解所用分析器的词汇切分行为。 通常情况下,当查询结果不是预期的结果时,可以将原因追踪到在查询时对字词进行切分的方式。 可以测试特定字符串的词汇切分,以确认输出。

包含一个或多个词条的任何文本输出都被视为查询执行的有效起点。 Azure AI 搜索将匹配包含任何或所有词条的文档,其中包括在分析文本期间发现的任何变体。

尽管听起来很简单,但 Azure AI 搜索中的查询执行的一个方面可能会产生意外结果,导致搜索结果增加而不是减少,因为更多的词条和运算符被添加到输入字符串中。 这种扩展是否会实际发生取决于是否包含 NOT 运算符(与 searchMode 参数设置组合使用,该参数设置决定了如何根据 ANDOR 行为解释 NOT)。 有关详细信息,请查看布尔运算符下的 NOT 运算符。

布尔运算符

可以在查询字符串中嵌入布尔运算符以提高匹配的精准率。 在简单语法中,布尔运算符是基于字符的。 文本运算符(如 AND 一词)不受支持。

字符 示例 使用情况
+ pool + ocean AND 运算。 例如,pool + ocean 规定文档必须同时包含这两个词。
| pool | ocean 找到其中一个词意味着 OR 运算找到了匹配项。 在此示例中,查询引擎会返回包含 poolocean 或两者的文档匹配项。 由于 OR 是默认连接运算符,因此也可以省略,这样 pool ocean 就等同于 pool | ocean
- pool - ocean NOT 运算会返回不包含该词的文档匹配项。

查询请求中的 searchMode 参数控制具有 NOT 运算符的字词是通过 AND 运算符还是通过 OR 运算符与查询中的其他字词组合到一起(假定其他字词没有布尔运算符)。 有效值包括 anyall

searchMode=any 通过包含更多结果来提高查询的查全率,且默认情况下 - 会被解释为“OR NOT”。 例如,pool - ocean 将匹配包含 pool 词条或不包含 ocean 词条的文档。

searchMode=all 通过包含更少结果来提高查询的精准率,且默认情况下“-”会被解释为“AND NOT”。 例如,对于 searchMode=any,查询 pool - ocean 将匹配包含术语“pool”的文档和不包含术语“ocean”的所有文档。 这对于 - 运算符来说可能是更直观的行为。 因此,如果想要优化搜索的查准率(而非查全率),且 用户在搜索中频繁使用 - 运算符,则应考虑使用 searchMode=all 而不是 searchMode=any

在决定 searchMode 设置时,请考虑不同应用程序中的查询的用户交互模式。 搜索信息的用户更有可能在查询中包含运算符,相对而言,电子商务网站具有更多的内置导航结构。

前缀查询

对于“开头为”查询,请添加后缀运算符 (*) 作为字词剩余部分的占位符。 若要添加后缀运算符,前缀查询必须以至少一个字母数字字符开头。

字符 示例 使用情况
* lingui* 会匹配“linguistic”或“linguini” 星号 (*) 表示一个或多个任意长度的字符,忽略大小写。

与筛选器类似,前缀查询查找完全匹配项。 因此,不存在相关性评分(所有结果的搜索分数均为 1.0)。 请注意,前缀查询可能会很慢,尤其是在索引较大且前缀包含的字符数较少的情况下。 另一种方法(如“边缘 n 元语法标记化”)执行速度可能较快。 使用前缀搜索的字词长度不能超过 1000 个字符。

简单语法只支持前缀匹配。 对于与一个词的末尾或中间匹配的后缀或中缀匹配,请使用适用于通配符搜索的完整 Lucene 语法

转义搜索运算符

在简单语法中,搜索运算符包含以下字符:+ | " ( ) ' \

如果其中的任何字符是索引中的令牌的一部分,请在查询中为其添加一个反斜杠 (\) 作为前缀对其进行转义。 例如,假设你使用自定义分析器完成了对整个术语的词汇切分,并且索引包含字符串“Luxury+Hotel”。 若要获得此令牌的完全匹配项,请插入转义字符:search=luxury\+hotel

为了让更典型的情况变得简单,此规则有两个不需要进行转义的例外:

  • 仅当 NOT 运算符 - 是空格之后的第一个字符时才需要对其进行转义。 如果 - 位于中间(例如在 3352CDD0-EF30-4A2E-A512-3B30AF40F3FD 中),则不需要对其进行转义。

  • 仅当后缀运算符 * 是空格之前的最后一个字符时才需要对其进行转义。 如果 * 位于中间(例如在 4*4=16 中),则不需要对其进行转义。

注意

默认情况下,标准分析器会在词法分析时删除连字符、空格、& 符和其他字符,并在这些字符处拆分单词。 如果需要在查询字符串中保留特殊字符,则可能需要使用一个分析器将它们保留在索引中。 可供选择的一些项包括 Azure 自然语言分析器(它会保留带连字符的单词)和自定义分析器(用于更复杂的模式)。 有关详细信息,请参阅部分词语、模式和特殊字符

对 URL 中的不安全及保留字符进行编码

请确保对 URL 中的所有不安全字符和保留字符进行编码。 例如,“#”是不安全字符,因为它是 URL 中的片段/定位标识符。 如果用于 URL,则该字符必须编码为 %23。 由于“&”和“=”在 Azure AI 搜索中分隔参数并指定值,因而是保留字符的示例。 有关详细信息,请参阅 RFC1738:统一资源定位器 (URL)

不安全字符为 " ` < > # % { } | \ ^ ~ [ ]。 保留字符为 ; / ? : @ = + &

特殊字符

特殊字符的范围可以从货币符号(如“$”或“€”)到表情符号。 许多分析器(包括默认标准分析器)在索引编制过程中会排除特殊字符,这意味着这些字符不会呈现在索引中。

如果需要呈现特殊字符,你可以分配一个保留这些字符的分析器:

  • 空格分析器将空格分隔的任何字符序列视为标记(因此“❤”表情符号将被视为标记)。

  • 诸如 Azure 英语分析器(en.microsoft)之类的语言分析器会将“$”或“€”字符串视为标记。

要进行确认,你可以测试分析器来查看为给定字符串生成的标记。 正如你所料,你可能无法通过单个分析器完成完全的标记化。 一个变通方法是创建包含相同内容的多个字段,但具有不同的分析器分配(例如 description_endescription_fr 等用于语言分析器)。

使用 Unicode 字符时,请确保在查询 URL 中正确转义了符号(例如,对于“❤”,将使用转义序列 %E2%9D%A4+)。 Postman 会自动执行此转换。

优先级(分组)

可以使用圆括号创建子查询,其包括附加说明语句中的运算符。 例如,motel+(wifi|luxury) 将搜索包含“motel”术语以及“wifi”或“luxury”(或两者)的文档。

查询大小限制

如果应用程序以编程方式生成搜索查询,则建议将其设计为不会生成无限大小的查询。

  • 对于 GET,URL 的长度不能超出 8 KB。

  • 对于请求正文包含 search 和其他参数(例如 filterorderby)的 POST(以及任何其他请求),最大大小为 16 MB。 其他限制包括:

    • 搜索子句的最大长度为 100,000 个字符。
    • search(用 AND 或 OR 分隔的表达式)中的最大子句数为 1024。
    • 对于前缀搜索,搜索词的最大大小为 1000 个字符。
    • 此外,查询中任何单个术语的大小限制为大约 32 KB。

有关查询限制的详细信息,请参阅 API 请求限制

后续步骤

若要以编程方式构造查询,请查看 Azure AI 搜索中的全文搜索,了解查询处理的各个阶段以及文本分析的影响。

还可以查看以下文章,详细了解查询构造: