【发布时间】:2021-04-10 09:26:15
【问题描述】:
如何根据条件过滤文档数组中的记录?
{
"_id" : ObjectId("5ff32c8b6cff64b8582a7c12"),
"Transaction" : [
{
"StatusCode" : "1",
"Amount" : NumberDecimal("300"),
"CreatedDateTime" : ISODate("2021-01-01T10:27:41.746Z")
},
{
"StatusCode" : "2",
"Amount" : NumberDecimal("-750"),
"CreatedDateTime" : ISODate("2021-01-02T10:27:41.746Z")
},
{
"StatusCode" : "1",
"Amount" : NumberDecimal("1500"),
"Date" : ISODate("2021-01-03T10:27:41.746Z")
}
]
}
在上述示例数据中,结果应按“status-code”分组,并按日期获取最后一笔交易金额和状态码。
查询:
[{$unwind: {
path: '$Transaction'
}}, {$sort: {
"Transaction.CreatedDateTime":1
}}, {$group: {
_id: { StatusCode : '$Transaction.StatusCode'},
Paid: {
$last: '$Transaction.Amount'
}
}}, {$project: {
_id :0,
StatusCode : '$_id.StatusCode',
Paid : '$Paid'
}}]
查询结果:
{
"StatusCode" : "1",
"Paid" : "1500"
}
{
"StatusCode" : "2",
"Paid" : "-750"
}
从这个查询结果中,我们需要比较状态码“1”和“2”的“付费”值。如果状态码“2”的支付价值不等于支付价值状态码“1”,则单独保留状态码“1”的记录,忽略状态码“2”的记录。
预期结果:
{
"StatusCode" : "1",
"Paid" : "1500"
}
【问题讨论】:
-
查询完全符合您的要求:“按状态代码分组并按日期和状态代码获取最后一笔交易金额”(但是缺少
{$sort: {"Transaction.Date": 1}})。第二句“状态码的金额值应该是一样的”我没看懂。和什么一样?什么是“状态码数量”? -
金额应与两个状态代码 [1 和 2] 匹配,否则忽略状态代码 =2 类别记录。例如:此处金额值 1500 不等于金额值 750。
-
还是不清楚。 1500 不等于值 750,根据您的要求应该是“记录应该被删除”,即在这种情况下查询不应该返回任何内容。
-
您有两个带有
StatusCode: 1的元素 - 哪一个与什么比较?当你说如果状态码2的支付值不等于状态码1的支付值,保持状态码1那么这等于简单的“忽略状态码2,总是取状态码的值1"(因为如果相等则状态 1 = 状态 2)我放弃了!
标签: arrays mongodb mongodb-query aggregation-framework