我不知道是否有这样的词,猜猜有,但是现在我无法解释它比“数组包含数组中的项目”更好。
这可能听起来很奇怪,但实际上并非(我认为),而且我很难弄清楚如何在Azure CosmosDB中做到这一点。
到此为止。我有一个这样的文件(简化):
{
"id": "2a62fcf4-988f-4ebe-aedc-fb0c664b85d8",
"Title": "Seks års fængsel for overgreb",
"ZipCodes": [
{
"Code": "6500",
"Name": "Vojens",
"FoundViaTerm": "Vojens"
},
{
"Code": "6400",
"Name": "Sønderborg",
"FoundViaTerm": "Sønderborg"
},
{
"Code": "6700",
"Name": "Esbjerg",
"FoundViaTerm": "Esbjerg"
}
],
"_rid": "k1sVAPf7SQAMAAAAAAAAAA==",
"_self": "dbs/k1sVAA==/colls/k1sVAPf7SQA=/docs/k1sVAPf7SQAMAAAAAAAAAA==/",
"_etag": "\"00001000-0000-0000-0000-5a14898e0000\"",
"_attachments": "attachments/",
"_ts": 1511295374
}
好的,现在我想查询这样的文档并查找所有文件,其中ZipCodes.Code位于zipcodes列表中,例如。 ('6500','2700')。
我在这里很难...
我找到了ARRAY_CONTAINS方法并且它有效,如果我只输入一个邮政编码 - 我的问题是我带有一个列表。
希望有人能提前帮助,谢谢。
答案 0 :(得分:7)
根据我的经验,expr
方法中的ARRAY_CONTAINS (arr_expr, expr [, bool_expr])
不支持列表参数。
根据您的情况,我建议您在Cosmos DB中使用UDF。
我创建了3个示例文档作为您的描述。
[
{
"id": "1",
"zip": [
{
"code": "1111"
},
{
"code": "2222"
}
]
},
{
"id": "2",
"zip": [
{
"code": "2222"
},
{
"code": "3333"
}
]
},
{
"id": "3",
"zip": [
{
"code": "4444"
},
{
"code": "1111"
},
{
"code": "2222"
}
]
}
]
请参阅以下UDF代码片段:
function test(zipcode){
var arrayList = ["1111","2222"]
var ret = false ;
for(var i=0 ;i <zipcode.length;i++){
if(arrayList.indexOf(zipcode[i].code)){
ret= true;
}else{
ret = false;
break;
}
}
return ret;
}
您可以选择zip数组(从c中选择c.zip),然后循环结果并使用zip[i]
参数在代码中调用上面的UDF。
希望它对你有所帮助。
仅供参考:
使用Cosmos DB SQL APIs中的IN运算符查询列表条件中包含的条目。
喜欢
SELECT * FROM c WHERE c.ZipCodes[0].Code IN ("6500", "6700")
或
SELECT * FROM c JOIN zc IN c.ZipCodes WHERE zc.Code IN ("2720", "2610")
答案 1 :(得分:0)
除了使用UDF看起来是更简单的选择之外,我不会在查询的过滤器中使用UDF,因为它会损害查询的性能。我在工作环境中遇到了相同的问题,在该环境中,事物被设计为使用UDF来帮助查询,但现实情况是,大多数情况下,我们使用单个值进行查询,而使用UDF实际上会在查询中产生结果。不使用索引。因此,在这种情况下,如果您需要验证数组中的多个值,具体取决于您需要验证的值的数量,则始终可以编写类似ARRAY_CONTAINS(c,1)或ARRAY_CONTAINS(c,2)或...之类的东西。
它看起来不是很好的解决方案,但是可以确保它使用索引并在您的查询中表现最佳。
答案 2 :(得分:0)
您可以执行以下操作: 对于ZipCodes中的每个项目,您将获得一个zip并将其与要检查的代码数组进行比较。恕我直言,这比使用UDF更好。
{
query: '
SELECT DISTINCT value r
FROM root r
JOIN zip IN r.zipCodes
WHERE ARRAY_CONTAINS(@zipIds, zip, true)
',
parameters: [{name: "@zipIds", value: zipIds}]
}
ARRAY_CONTAINS的最后一个参数告诉该函数接受部分匹配。
答案 3 :(得分:0)
我想针对这个问题提出另一种解决方案。
以这种方式使用 EXISTS 和 ARRAY_CONTAINS:
SELECT * FROM c
哪里存在
(SELECT VALUE z from FROM z in c.ZipCodes WHERE ARRAY_CONTAINS(["6500","6700"], z))