【问题标题】:How can I select a filtered child document collection when querying a top level document in cosmos db在 cosmos db 中查询顶级文档时如何选择过滤的子文档集合
【发布时间】:2018-11-21 11:40:25
【问题描述】:

我正在尝试过滤使用 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": []
}

【问题讨论】:

  • 你有 order.amount 索引吗?
  • 不,我不是这个问题吗?
  • 是的,如果某些内容未编入索引,则无法对其进行过滤,即使已编入索引,它也必须至少是 Range 类型的索引。让我知道这是否有效,我会写下答案
  • 在 /orders/* 上添加了 Number 的范围索引,但没有效果,仍然返回 []
  • 您是否给了它一些时间来重新索引您的属性。你也打开了自动索引?还有数字的索引类型是什么?

标签: azure-cosmosdb


【解决方案1】:

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"
        }
     ]
}]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    相关资源
    最近更新 更多