DocumentDB查询数组

时间:2015-07-07 15:01:15

标签: sql arrays azure-cosmosdb

我的文档包含一个简单的(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”)的所有文档 - >文件“一”和“两”

2 个答案:

答案 0 :(得分:5)

您可以将JOIN运算符与IN运算符组合使用,该运算符用于与嵌套数组元素形成交叉积。

SELECT docs
FROM docs
JOIN tags IN docs.tags
WHERE tags IN ("B", "C")

请注意,因为您正在创建一个交叉产品,所以您将获得每个匹配子元素的结果,而不是每个文档的结果。

或者,您可以将多个ARRAY_CONTAINSOR运算符组合在一起,或者编写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)