我有一个集合,它将 child 的出生日期和时间存储在 mongodb 数据库中。用户可以创建一个时段,并根据该用户可以在该特定时段出生的 child 详细信息。例如,今天用户选择 08:00 AM - 09:30 AM,用户可以在屏幕上看到详细信息,我能够成功完成这一点。
我无法获取不属于任何时间段的 child 的详细信息。例如,用户创建了 4 个插槽 [08:00 AM - 09:30 AM、11:00 AM - 12:00、2:30 PM - 6:30 PM、09:00 PM - 09:30 PM] ,我想要获取不属于这四个时间段的 child 的详细信息。
首先,我将检索插槽集合中存在的插槽,然后从 Nodejs API 迭代每个插槽并将其发送到下面的代码并检索详细信息。
[
{ $match : {'BornTime': {$gte: start, $lte: end} } },
{ $project:{
"_id": 0,
"name":{$concat: [
{$cond:[{ $eq: ['status', 1] }, "Children Born", ""]},
{$cond:[{ $eq: ['status', 0] }, "Children Died", ""]},
]},
"childcount":'childcount'}},
{ $group: { _id: '$name', count: { $sum: 1 } , covers: { $sum: '$childcount' } } },
]
请帮我检索不属于任何槽位的详细信息。我无法发布该部分,因为我无法正确执行它,或者我不知道如何实现它,我尝试使用 $not,但无法成功。
如果需要对上述任何细节进行更多说明,请告诉我。
最佳答案
我认为您在这里的流程可以简化,并且还可以立即获得您想要的结果,而无需像您所说的那样“迭代”
假设我们使用问题中提到的四个插槽,并且我们正在寻找今天的结果。我会这样做,这将一次性对所有结果进行分类:
var today = new Date("2015-08-11T00:00:00.000Z"),
tomorrow = new Date("2015-08-12T00:00.000Z"),
slots = [
[new Date("2015-08-11T08:00:00.000Z"),new Date("2015-08-11T09:30:00.000Z")],
[new Date("2015-08-11T11:00:00.000Z"),new Date("2015-08-11T12:00:00.000Z")],
[new Date("2015-08-11T14:30:00.000Z"),new Date("2015-08-11T18:30:00.000Z")],
[new Date("2015-08-11T21:00:00.000Z"),new Date("2015-08-11T21:30:00.000Z")]
];
var stack = [];
for (var i = slots.length-1; i >= 0; i--) {
var rec = {
"$cond": [
{ "$and": [
{ "$gte": [ "$BornTime", slots[i][0] ]},
{ "$lte": [ "$BornTime", slots[i][1] ]}
]},
i
]
};
if ( stack.length == 0 ) {
rec["$cond"].push("noSlot");
} else {
var lval = stack.pop();
rec["$cond"].push(lval);
}
stack.push(rec);
}
var pipeline = [
// Match today
{ "$match":{ "BornTime": { "$gte": today, "$lt": tomorrow } } },
// Group
{ "$group": {
"_id": {
"name": {
"$cond": [
{ "$eq": [ "$status", 1 ] },
{ "$literal": "ChildrenBorn" },
{ "$literal": "ChildrenDied" }
]
},
"slot": stack[0]
},
"count": { "$sum": 1 },
"covers": { "$sum": "$childcount" }
}}
];
这实际上为管道阶段中的分组构建了“槽”条目,如下所示:
{
"$cond" : [
{
"$and" : [
{
"$gte" : [
"$BornTime",
ISODate("2015-08-11T08:00:00Z")
]
},
{
"$lte" : [
"$BornTime",
ISODate("2015-08-11T09:30:00Z")
]}
]
},
0,
{
"$cond" : [
{
"$and" : [
{
"$gte" : [
"$BornTime",
ISODate("2015-08-11T11:00:00Z")
]
},
{
"$lte" : [
"$BornTime",
ISODate("2015-08-11T12:00:00Z")
]
}
]
},
1,
{
"$cond" : [
{
"$and" : [
{
"$gte" : [
"$BornTime",
ISODate("2015-08-11T14:30:00Z")
]
},
{
"$lte" : [
"$BornTime",
ISODate("2015-08-11T18:30:00Z")
]
}
]
},
2,
{
"$cond" : [
{
"$and" : [
{
"$gte" : [
"$BornTime",
ISODate("2015-08-11T21:00:00Z")
]
},
{
"$lte" : [
"$BornTime",
ISODate("2015-08-11T21:30:00Z")
]
}
]
},
3,
"noSlot"
]
}
]
}
]
}
]
}
因此,每个“槽号”的返回取决于当前“BornTime”值落入每个槽的位置。如果它不属于任何槽,则返回“noSlot”值。
因此,在嵌套 $cond
的帮助下您可以通过一次查询获得所有结果。
关于node.js - 不在特定时间段内聚合数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31934300/