如何在 Azure 搜索中筛选数组
How to filter an array in Azure Search
我的索引中有以下数据,
{
"name" : "The 100",
"lists" : [
"2c8540ee-85df-4f1a-b35f-00124e1d3c4a;Bellamy",
"2c8540ee-85df-4f1a-b35f-00155c40f11c;Pike",
"2c8540ee-85df-4f1a-b35f-00155c02e581;Clark"
]
}
我必须获取列表中包含 Pike 的所有文档。
虽然完整的搜索查询适用于 Any,但我无法使用包含的内容。
$filter=lists/any(t: t eq '2c8540ee-85df-4f1a-b35f-00155c40f11c;Pike')
但是我不确定如何只使用 Pike 进行搜索。
$filter=lists/any(t: t eq 'Pike')
我猜 eq 寻找的是全文搜索,对于给定的数据结构,有没有什么方法可以让这个查询工作。
目前字段列表没有可搜索的 属性 只有可过滤的 属性。
eq
运算符查找精确的、区分大小写的匹配项。这就是它不匹配 'Pike'
的原因。您需要构建索引,以便可以轻松找到 'Pike' 之类的术语。您可以通过以下两种方式之一完成此操作:
- 索引文档时将 GUID 与名称分开。因此,不用将
"2c8540ee-85df-4f1a-b35f-00155c40f11c;Pike"
作为单个字符串进行索引,您可以将它们作为同一数组中的单独字符串进行索引,或者如果您需要按位置关联它们,则可能在两个不同的集合字段(一个用于 GUID,一个用于名称)中.
- 如果字段是
searchable
,您可以在分号上使用 new search.ismatch
function in your filter. Assuming the field is using the standard analyzer, full-text search will word-break,这样您应该能够只搜索“Pike”并获得匹配项。语法如下所示:$filter=search.ismatch('Pike', 'lists')
(如果查找“Pike”是您的过滤器所做的全部工作,您可以只使用 search
和 searchFields
参数来搜索 API而不是 $filter
。)如果“lists”字段尚未可搜索,您将需要添加一个新字段并重新索引“lists”值,或者使用新的从头开始重新创建索引字段定义。
更新
API 2019-05-06 及更高版本提供了一种解决此类问题的新方法。您现在可以使用复杂类型来表示结构化数据,包括在集合中。对于原始示例,您可以像这样构建数据:
{
"name" : "The 100",
"lists" : [
{ "id": "2c8540ee-85df-4f1a-b35f-00124e1d3c4a", "name": "Bellamy" },
{ "id": "2c8540ee-85df-4f1a-b35f-00155c40f11c", "name": "Pike" },
{ "id": "2c8540ee-85df-4f1a-b35f-00155c02e581", "name": "Clark" }
]
}
然后像这样直接查询 name
子字段:
$filter=lists/any(l: l/name eq 'Pike')
复杂类型的文档是 here。
我的索引中有以下数据,
{
"name" : "The 100",
"lists" : [
"2c8540ee-85df-4f1a-b35f-00124e1d3c4a;Bellamy",
"2c8540ee-85df-4f1a-b35f-00155c40f11c;Pike",
"2c8540ee-85df-4f1a-b35f-00155c02e581;Clark"
]
}
我必须获取列表中包含 Pike 的所有文档。
虽然完整的搜索查询适用于 Any,但我无法使用包含的内容。
$filter=lists/any(t: t eq '2c8540ee-85df-4f1a-b35f-00155c40f11c;Pike')
但是我不确定如何只使用 Pike 进行搜索。
$filter=lists/any(t: t eq 'Pike')
我猜 eq 寻找的是全文搜索,对于给定的数据结构,有没有什么方法可以让这个查询工作。
目前字段列表没有可搜索的 属性 只有可过滤的 属性。
eq
运算符查找精确的、区分大小写的匹配项。这就是它不匹配 'Pike'
的原因。您需要构建索引,以便可以轻松找到 'Pike' 之类的术语。您可以通过以下两种方式之一完成此操作:
- 索引文档时将 GUID 与名称分开。因此,不用将
"2c8540ee-85df-4f1a-b35f-00155c40f11c;Pike"
作为单个字符串进行索引,您可以将它们作为同一数组中的单独字符串进行索引,或者如果您需要按位置关联它们,则可能在两个不同的集合字段(一个用于 GUID,一个用于名称)中. - 如果字段是
searchable
,您可以在分号上使用 newsearch.ismatch
function in your filter. Assuming the field is using the standard analyzer, full-text search will word-break,这样您应该能够只搜索“Pike”并获得匹配项。语法如下所示:$filter=search.ismatch('Pike', 'lists')
(如果查找“Pike”是您的过滤器所做的全部工作,您可以只使用search
和searchFields
参数来搜索 API而不是$filter
。)如果“lists”字段尚未可搜索,您将需要添加一个新字段并重新索引“lists”值,或者使用新的从头开始重新创建索引字段定义。
更新
API 2019-05-06 及更高版本提供了一种解决此类问题的新方法。您现在可以使用复杂类型来表示结构化数据,包括在集合中。对于原始示例,您可以像这样构建数据:
{
"name" : "The 100",
"lists" : [
{ "id": "2c8540ee-85df-4f1a-b35f-00124e1d3c4a", "name": "Bellamy" },
{ "id": "2c8540ee-85df-4f1a-b35f-00155c40f11c", "name": "Pike" },
{ "id": "2c8540ee-85df-4f1a-b35f-00155c02e581", "name": "Clark" }
]
}
然后像这样直接查询 name
子字段:
$filter=lists/any(l: l/name eq 'Pike')
复杂类型的文档是 here。