代码之家  ›  专栏  ›  技术社区  ›  Dean MacGregor

查询Azure Cosmos以查找具有所有元素的项目

  •  2
  • Dean MacGregor  · 技术社区  · 3 年前

    假设我的数据库中有几个示例项目,看起来如下:

    示例1:

    {
        'id': 'someid',
        'columns': ['apple', 'banana'],
        'filters': {'car': 'red', 'truck': 'blue'}
    }
    

    示例2:

    {
        'id': 'someid',
        'columns': ['apple', 'banana', 'carrots'],
        'filters': {'truck': 'blue', 'car': 'red', 'boat':'green'}
    }
    

    快进到现在,我有一套新的 columns 和的 filters 可能看起来像:

    newcolumns=['banana','apple'] newfilters={'truck':'blue', 'car':'red'}

    我想做这样的查询

    select *
    from f
    where f.columns=newcolumns and f.filters=newfilters
    

    但我不在乎顺序,他们必须完全匹配。两个集合都不能是另一个集合的超集合或子集。因此,在这种情况下,我的查询应该返回示例1,而不是示例2。

    请注意,我的问题有两个部分 匹配的答案是 this 但是 过滤器 字段不是列表,因此语法不相同。

    1 回复  |  直到 3 年前
        1
  •  1
  •   David Makogon    3 年前

    你不能像以前那样对两个数组进行相等比较来真正匹配:

    where f.columns=newcolumns and f.filters=newfilters
    

    相反,使用Cosmos DB的内置 ARRAY_CONTAINS() 与…结合 ARRAY_LENGTH() .

    自从 columns 是一个标量数组,它看起来像:

    WHERE ARRAY_CONTAINS(c.columns, "banana")
    AND ARRAY_CONTAINS(c.columns, "apple")
    

    对于 filters ,这不是数组,所以…首先检查以确保定义了键,然后检查值是否正确:

    WHERE IS_DEFINED(c.filters.truck) AND c.filters.truck="blue"
    AND IS_DEFINED(c.filters.car) AND c.filters.car="red"
    

    注意:将过滤器转换为子文档可能是个好主意,因为您当前的模式是 反模式 (使用值作为键)。类似于:

    {
        "filters": [
           { "vehicleType": "truck", "color": "blue" },
           { "vehicleType": "car", "color": "red" }
    }
    

    在这一点上,你可以与 ARRAY_CONTAINS() 再一次类似于:

    WHERE ARRAY_CONTAINS(c.filters, { "vehicleType": "truck", "color": "blue"}, true)