node.js - 在 mongo 聚合中使用当前文档键
问题描述
我正在处理一个对我的订单进行排序的查询,为此我使用带有以下选项的 mongo 聚合。
$match
$lookup
$unwind
$sort
$skip
$limit
我的整个查询看起来像这样。
[
{ "$match": query },
{
"$lookup": {
"from": "orderstatuslogs",
"localField": "_id",
"foreignField": "orderId",
"as": "filtered_statuses"
}
},
{
"$lookup": {
"from": "orderstatuslogs",
"localField": "_id",
"foreignField": "orderId",
"as": "order_statuses"
}
},
{
"$unwind": "$filtered_statuses"
},
{
"$match": {
'filtered_statuses.status': status
}
},
{
"$sort": { 'filtered_statuses.createdAt': sort }
},
{ '$skip': skip },
{ "$limit": limit },
]
我目前面临的问题是第二个$match
,'filtered_statuses.status': status
. 匹配状态应该来自当前文档,类似这样$order_status
,我们order_status
在每个文档中都调用了密钥,我想使用该密钥进行匹配,但我不明白如何使用该密钥。
我的整个文档看起来像这样。
{
"_id" : ObjectId("5d3496e9bf9c0a1b0a4bbdd1"),
"products" : [
ObjectId("5d3496e9bf9c0a1b0a4bbdd0")
],
"isGiftCard" : true,
"order_status" : "NEW",
"total_price" : 240,
"discount" : 0,
"isConcierge" : false,
"note" : "",
"time" : "2019-05-12T10:28:43.316Z",
"userId" : ObjectId("5cfcaf6d249ff4a6340d9385"),
"trackId" : "891383",
"isPackaged" : false,
"sender_details" : ObjectId("5cfcaf6d249ff4a6340d9385"),
"timeSlot" : ObjectId("5cfcfc2e2ae5a0e3d43af363"),
"createdAt" : ISODate("2019-07-21T16:46:33.859Z"),
"updatedAt" : ISODate("2019-07-21T17:26:34.243Z"),
"__v" : 0,
"recipient" : ObjectId("5cfcfbf32ae5a0e3d43af35e"),
"recipient_details" : ObjectId("5d349cc5a8f5cf1d345934d8"),
"delivery_method" : ObjectId("5cfcfbb32ae5a0e3d43af35a"),
"gift_card" : ObjectId("5d0107009786972878fcf811"),
"gift_card_text" : "Eid Mabrook",
"payment" : ObjectId("5d349cc8a8f5cf1d345934d9"),
"payment_type" : ObjectId("5cfcfb802ae5a0e3d43af358"),
"filtered_statuses" : {
"_id" : ObjectId("5d349cd5a8f5cf1d345934da"),
"status" : "NEW",
"active" : true,
"userId" : ObjectId("5cfcaf6d249ff4a6340d9385"),
"orderId" : ObjectId("5d3496e9bf9c0a1b0a4bbdd1"),
"createdAt" : ISODate("2019-07-21T17:11:49.796Z"),
"updatedAt" : ISODate("2019-07-21T17:11:49.796Z"),
"__v" : 0
},
"order_statuses" : [
{
"_id" : ObjectId("5d349cd5a8f5cf1d345934da"),
"status" : "NEW",
"active" : true,
"userId" : ObjectId("5cfcaf6d249ff4a6340d9385"),
"orderId" : ObjectId("5d3496e9bf9c0a1b0a4bbdd1"),
"createdAt" : ISODate("2019-07-21T17:11:49.796Z"),
"updatedAt" : ISODate("2019-07-21T17:11:49.796Z"),
"__v" : 0
}
]
}
正如您在我当前的文档中看到的那样,我有order_status
并且我想在$match
查询中使用相同的键来过滤我的某些结果。
有人可以帮我吗?
我已经搜索了很多,但没有找到正确的方法。
提前谢谢大家。
解决方案
首先,您应该使用阶段中的let
键$lookup
来创建可以引用到$match
阶段的变量。
其次,您应该使用以下键中的$match
阶段:pipeline
$lookup
{
"$lookup": {
"from": "orderstatuslogs",
"let": { order_status: "$order_status" }, // $order_status will refer to the order_status field in the main document
"localField": "_id",
"foreignField": "orderId",
"as": "filtered_statuses",
"pipeline": {
"$match": {
$expr: { $eq: [ "$status", "$$order_status" ] }
}
}
}
},
最后,您可以删除第二个 $match 阶段,因为它不再需要了。
推荐阅读
- javascript - 使用键 javascript 将嵌套的 json 转换为 CSV
- yocto - 来自外部设备的音频音量
- javascript - 角度形式的条件要求验证
- python - Why does set() in set() not raise a TypeError, unlike {} in set(), [] in set(), set() in {}, [] in {}, or {} in {}?
- azure - Azure CosmosDb 分区键 - 不同的架构
- javascript - 循环 - 如何在每个循环中添加一个变量
- dependency-injection - c#中的松散耦合
- python - 当用户输入的参数多于函数可以处理的参数时,如何获取与 TypeError 相关的异常
- json - json_query 上的 Ansible 断言
- c# - 如何绑定到集合的项目属性?