node.js - 不在特定时间段内聚合数据

标签 node.js mongodb mongodb-query aggregation-framework

我有一个集合,它将 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/

相关文章:

mongodb - 全文检索 MongoDB/Mongoengine

java - MongoOperations 添加/删除 json 到 MongoDB

node.js - Nodejs 流与 Braintree?

node.js - 如何使用 Node JS 连接 Redshift 数据库

node.js - 我是否只需使用具有快速渲染功能的模板语言?

mongodb单数据库复制

node.js - 如何更新多个文档?

python - 高效分页查询结果

MongoDB $group 和带有计算列的显式组形成

node.js - 在mongodb聚合中仅提取$project中键值对中的值