首页 > 解决方案 > 在 cosmos db 中查询顶级文档时如何选择过滤的子文档集合

问题描述

我正在尝试过滤使用 cosmos db 中的 sql api 查询父文档时返回的子文档。

例如给出这个文件:

{
    "customerName": "Wallace",
    "customerReference": 666777,
    "orders": [
    {
        "date": "20181105T00:00:00",
        "amount": 118.84,
        "description": "Laptop Battery"
    },
    {
        "date": "20181105T00:00:00",
        "amount": 81.27,
        "description": "Toner"
    },
    {
        "date": "20181105T00:00:00",
        "amount": 55.12,
        "description": "Business Cards"
    },
    {
        "date": "20181105T00:00:00",
        "amount": 281.00,
        "description": "Espresso Machine"
    }]    
    }

我想查询客户以检索超过 100.00 的名称、参考和订单以产生这样的结果

[{
"customerName": "Wallace",
"customerReference": 666777,
"orders": [
    {
        "date": "20181105T00:00:00",
        "amount": 118.84,
        "description": "Laptop Battery"
    },           
    {
        "date": "20181105T00:00:00",
        "amount": 281.00,
        "description": "Espresso Machine"
    }]
}]

我到目前为止的查询如下

SELECT c.customerName, c.customerReference, c.orders
from c
where c.customerReference = 666777
and c.orders.amount > 100

这返回一个空集

[]

如果您删除“and c.orders.amount > 100”,它将匹配文档并返回所有订单。

为了重现这个问题,我简单地设置了一个新数据库,添加了一个新集合并将 json 示例复制为唯一的文档。索引策略保留为我在下面复制的默认值。

{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
    {
        "path": "/*",
        "indexes": [
            {
                "kind": "Range",
                "dataType": "Number",
                "precision": -1
            },
            {
                "kind": "Range",
                "dataType": "String",
                "precision": -1
            },
            {
                "kind": "Spatial",
                "dataType": "Point"
            }
        ]
    }
],
"excludedPaths": []
}

标签: azure-cosmosdb

解决方案


Cosmos DB 不支持我在原始查询中尝试的深度过滤。

要获得所描述的结果,您需要使用结合使用 ARRAY 和 VALUE 的子查询,如下所示:

SELECT 
    c.customerName, 
    c.customerReference, 
    ARRAY(SELECT Value ord from ord in c.orders WHERE ord.amount > 100) orders
from c
    where c.customerReference = 666777

注意“ord”的使用——“order”是保留字。

然后查询会产生正确的结果 - 例如

[{
    "customerName": "Wallace",
    "customerReference": 666777,
    "orders": [
        {
            "date": "20181105T00:00:00",
            "amount": 118.84,
            "description": "Laptop Battery"
        },           
        {
            "date": "20181105T00:00:00",
            "amount": 281.00,
            "description": "Espresso Machine"
        }
     ]
}]

推荐阅读