【问题标题】:DocumentDB queries with arrays带有数组的 DocumentDB 查询
【发布时间】:2015-09-25 03:54:05
【问题描述】:

我有一个带有简单(字符串)数组属性的文档。

{
     "id": "one",
     "tags": ["A", "B"]
}

{
     "id": "two",
     "tags": ["A", "C"]
}

要检查一个值是否是数组的一部分,我可以使用 ARRAY_CONTAINS

SELECT * FROM c WHERE ARRAY_CONTAINS(c.tags, "B")

将返回文档“一个”。

如何查询包含数组中可能值列表的文档?

返回标签数组中至少一个值为 IN("B", "C") 的所有文档。
-> 文件“一”和“二”

【问题讨论】:

    标签: sql arrays azure-cosmosdb


    【解决方案1】:

    我已经设法使用 Andrew Liu 建议的用户定义函数找到解决方案,因为 - 正如他所提到的 - 这种 JOIN 方法正在返回叉积,因此每一个匹配都是作为结果给出的。

    在我的情况下,我需要确定用户是否有权查看文档 - 通过组分配访问它。每个用户都有他的组列表,每个文档都有一个允许查看其内容的组列表。

    对于所描述的示例,假设我们有一个允许组 ["g1","g2","g3"] 的文档和一个可以查看组 ["g1","g3"] 中的文档的用户。

    使用我们的 SQL JOIN 方法,当我们查找可用文档时,上述文档将被返回两次。如果 Distinct 函数可用于 DocumentDB,也许我不会关心这一点,但目前它不是(但您仍然可以vote 使用它)。

    UDF 是使用 javascript 定义的,因此负责确定两个列表(数组)是否具有共同元素的代码如下所示:

    function(array1, array2) {
       return array1.some(function (v) {
           return array2.indexOf(v) >= 0;
       });
    }
    

    要从 C# 代码中定义这样的脚本,你可以按照这个 sn-p:

    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);
    }
    

    最后运行 SQL 查询,记住每次用户定义函数调用之前需要的“udf”前缀:

    SELECT * FROM docs 
    WHERE udf.ArraysHasCommonElem(your_array1, your_array2)
    

    【讨论】:

    【解决方案2】:

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

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

    请注意,由于您正在创建一个叉积,您将获得每个匹配子元素的结果,而不是每个文档。

    或者,您可以将多个 ARRAY_CONTAINSOR 运算符组合在一起,或者编写一个 UDF。

    【讨论】:

    • 谢谢!这几乎解决了它。没有 * 用于连接查询和 () 而不是 []
    • 糟糕 - 已修复查询 :)
    • 现在可以使用不同的功能,您可以使用 SELECT DISTINCT docs from ...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-26
    • 2018-03-08
    • 2018-05-06
    • 2016-06-14
    相关资源
    最近更新 更多