在mongodb集合中,我有以下类似的价格:
id date value
A 1 Jan 18 1
A 2 Jan 18 0
A 3 Jan 18 0
B 14 Jan 18 4
B 15 Jan 18 5
B 16 Jan 18 0
C 2 Jan 18 4
C 3 Jan 18 4
C 5 Jan 18 3
使用mongodb聚合管道(mongo 3.4),我试图找出每个id,值的日期从非零变为0,以及这些记录的“ id组”。 >
当记录具有特定值时,我可以找到第一个和最后一个日期:
{
"$addFields": {
"date": {
"$dateFromString": {
"dateString": "$date"
}
}
}
},
{
$group: {
_id: {
"id": "$id",
"value": "$value"
},
"first": {
"$first": "$date"
},
"last": {
"$last": "$date"
}
}
},
{
"$match": {
"_id.value": 0
}
}
https://mongoplayground.net/p/moBRI2Q7aGu
这给了我(注意,缺少ID C,因为它没有0值):
id value first last
A 0 2 Jan 18 3 Jan 18
B 0 16 Jan 18 16 Jan 18
如果我查看“第一个”日期,那是那些值首先从非零变为0的日期。
但是,我希望看到在某个时间点从非零变为0的那些值的整个“ id组”。所以我的预期结果是:
id value first last
A 1 1 Jan 18 1 Jan 18
A 0 2 Jan 18 3 Jan 18
B 4 14 Jan 18 14 Jan 18
B 5 15 Jan 18 15 Jan 18
B 0 16 Jan 18 16 Jan 18
要获取此信息,我需要在上述管道匹配之前访问group阶段,所以https://mongoplayground.net/p/YTP-NBJtO4R,并使用第一个聚合管道的结果集对此进行过滤。我是通过第一个结果集上的左联接在熊猫中执行此操作的,但这似乎不太好。
所以现在我有两个不同的管道,这似乎有点不方便。理想情况下,最后一个结果集将来自单个聚合管道。有什么想法吗?
答案 0 :(得分:1)
我认为这应该为您提供所需的输出:
db.collection.aggregate([
{
"$addFields": {
"date": {
"$dateFromString": {
"dateString": "$date"
}
}
}
},
{
"$sort": {
date: 1
}
},
{
$group: {
_id: {
"id": "$id",
"value": "$value"
},
"first": {
"$first": "$date"
},
"last": {
"$last": "$date"
},
"data": {
"$push": "$$ROOT"
}
}
},
{
"$sort": {
first: 1
}
},
{
"$group": {
_id: "$_id.id",
last_value: {
$last: "$_id.value"
},
first_date_for_last_value: {
$last: "$first"
},
last_date_for_last_value: {
$last: "$last"
},
all_values: {
$push: {
id: "$$ROOT._id.id",
value: "$$ROOT._id.value",
first: "$first",
last: "$last"
}
}
}
},
{
"$match": {
"last_value": 0
}
}
])
如果需要的只是“ all_values”中的数据,则可以选择添加$ project和$ unwind阶段。