azure-cosmosdb - 在 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": []
}
解决方案
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"
}
]
}]
推荐阅读
- go - 在 Windows 10 的 $ANDROID_HOME/ndk-bundle 和 $ANDROID_NDK_HOME 中找不到 Android NDK
- histogram-equalization - 瞳孔错误 = cv2.equalizeHist(frame[y+(h*0.25):(y+h), x:(x+w)])
- kubernetes - K8S 节点可以托管属于不同命名空间的 Pod 吗?
- javascript - JS 初学者 - 函数和 DOM,无法弄清楚我的错误 - 将 DOM 用于 func 参数
- python - 如何向列表中的字典添加值?
- docker - Docker Desktop 3.3.0+ 在端口 443 上中断 SSH:如何修复?
- sql - 为什么 SQL 中的 NOT IN 运算符也会过滤掉空值?
- python - Django中处理递归模板显示的策略
- reactjs - 映射一组对象以在 React 中显示它
- c - 如何为用户添加选项以再次运行操作?