我有一个包含一组文档的MongoDB集合。每个文档都有一个ISODate date
和一个整数id
(不是_id
)。如果集合中的文档中包含字段值id: X
,则date: D
的{{1}}被认为存在。所以,例如:
{ id: X, date: D }
我希望随着时间的推移跟踪{ id: 1, date: 1/1/2000 }
{ id: 1, date: 1/2/2000 }
{ id: 1, date: 1/3/2000 }
{ id: 1, date: 1/4/2000 }
{ id: 2, date: 1/2/2000 }
{ id: 2, date: 1/3/2000 }
{ id: 3, date: 1/3/2000 }
,因为它们是日常创建和销毁的。使用上述数据,在1/1/2000至1/4/2000的日期范围内:
id
我认为解决这个问题的最佳方法是逐日循环,查看今天和第二天之间存在的1/1/2000: id 1 is created
1/2/2000: id 2 is created
1/3/2000: id 3 is created
1/4/2000: id 2 is destroyed
1/4/2000: id 3 is destroyed
,并执行一组差异。例如,要获得在1/2/2000创建和销毁的一组id,我需要在两天之间执行两组数组差异:
id
我可以使用var A = [ <ids that exist on 1/1/2000> ];
var B = [ <ids that exist on 1/2/2000> ];
var created_set = set_difference(B, A); // Those in B and not in A
var destroyed_set = set_difference(A, B); // Those in A and not in B
命令获取find()
和A
的游标,但我不知道如何在两个游标之间执行B
。
我的另一个选择是使用聚合管道,但我无法考虑如何以我可以使用set_difference
运算符的方式来表达管道。
作为一名MongoDB新手,我确信我以错误的方式思考问题。当然这是可以做到的事情?我错过了什么?
答案 0 :(得分:2)
db.mystuff.aggregate([
{$group: {_id: '$id', created: {$first: '$date'}, destroyed: {$last: '$date'}}}
])
答案 1 :(得分:1)
假设您有以下样本集:
db.collection.insert([
{ id: 1, date: ISODate("2000-01-01") },
{ id: 1, date: ISODate("2000-01-02") },
{ id: 1, date: ISODate("2000-01-03") },
{ id: 1, date: ISODate("2000-01-04") },
{ id: 2, date: ISODate("2000-01-02") },
{ id: 2, date: ISODate("2000-01-03") },
{ id: 3, date: ISODate("2000-01-03") }
]);
以下聚合将为您提供使用$setDifference
运算符实现目标的方向:
var start = new Date(2000, 0, 1);
var end = new Date(2000, 0, 2)
db.collection.aggregate([
{
"$match":{
"date": {
"$gte": start,
"$lte": end
}
}
},
{
$group: {
_id: "$date",
"A": {
"$addToSet": {
"$cond": [
{ "$eq": [ "$date", start ] },
"$id",
false
]
}
},
"B": {
"$addToSet": {
"$cond": [
{ "$eq": [ "$date", end ] },
"$id",
false
]
}
}
}
},
{
"$project": {
"A": {
"$setDifference": [ "$A", [false] ]
},
"B": {
"$setDifference": [ "$B", [false] ]
}
}
},
{
"$project": {
"_id": 0,
"date": "$_id",
"created_set": {
"$setDifference": [ "$B", "$A" ]
},
"destroyed_set": {
"$setDifference": [ "$A", "$B" ]
}
}
}
]);
<强>输出强>:
{
"result" : [
{
"date" : ISODate("2000-01-02T00:00:00.000Z"),
"created_set" : [2, 1],
"destroyed_set" : []
},
{
"date" : ISODate("2000-01-01T00:00:00.000Z"),
"created_set" : [],
"destroyed_set" : [1]
}
],
"ok" : 1
}