我的文档包含一个简单的(string-)数组属性。
"A" -as [char] -as [int]
要检查,如果值是数组的一部分,我可以使用ARRAY_CONTAINS
PS C:\> $errors = @()
PS C:\> $script = "+'A'['']"
PS C:\> $tokens = [System.Management.Automation.PSParser]::Tokenize($script,[ref]$errors)
PS C:\> $tokens | select Content, Type
Content Type
------- ----
+ Operator
A String
[ Operator
String
] Operator
将返回文档“one”。
如何查询包含数组中可能值列表的文档?
返回标签数组中至少有一个值为IN(“B”,“C”)的所有文档 - >文件“一”和“两”
答案 0 :(得分:5)
您可以将JOIN
运算符与IN
运算符组合使用,该运算符用于与嵌套数组元素形成交叉积。
SELECT docs
FROM docs
JOIN tags IN docs.tags
WHERE tags IN ("B", "C")
请注意,因为您正在创建一个交叉产品,所以您将获得每个匹配子元素的结果,而不是每个文档的结果。
或者,您可以将多个ARRAY_CONTAINS
与OR
运算符组合在一起,或者编写UDF。
答案 1 :(得分:3)
我已经设法使用Andrew Liu建议的用户定义函数来解决问题,因为 - 正如他所提到的 - 这种JOIN
方法正在返回交叉产品,因此每次匹配都会得到结果。< / p>
在我的情况下,我需要确定用户是否有权查看该文档 - 它是通过组分配来达到的。每个用户都有他的组列表,每个文档都有一个允许查看其内容的组列表。
对于所描述的示例,假设我们有一个文档允许组[&#34; g1&#34;,&#34; g2&#34;,&#34; g3&#34;]和一个可以使用的用户分组查看文件[&#34; g1&#34;,&#34; g3&#34;]。
使用我们的SQL JOIN
方法,当我们查找可用文档时,上述文档将被返回两次。如果Distinct函数可用于DocumentDB,也许我不会关心这一点,但目前它不是(但你仍然可以vote)。
使用javascript定义UDF,因此负责确定两个列表(数组)是否具有公共元素的代码如下所示:
function(array1, array2) {
return array1.some(function (v) {
return array2.indexOf(v) >= 0;
});
}
要从C#代码定义此类脚本,您可以按照以下代码段进行操作:
UserDefinedFunction udf =
_client.CreateUserDefinedFunctionQuery(_collection.UserDefinedFunctionsLink)
.Where(x => x.Id == "ArraysHasCommonElem")
.AsEnumerable()
.FirstOrDefault();
if (udf == null)
{
udf = new UserDefinedFunction
{
Body = @"function(array1, array2) {
return array1.some(function (v) {
return array2.indexOf(v) >= 0;
});
}",
Id = "ArraysHasCommonElem"
};
await _client.CreateUserDefinedFunctionAsync(collectionUri.SelfLink, udf);
}
最后运行有关&#39; udf&#39;的工作SQL查询记忆。每个用户定义函数调用之前需要的前缀:
SELECT * FROM docs
WHERE udf.ArraysHasCommonElem(your_array1, your_array2)