汇总数据不在特定时段

时间:2015-08-11 06:03:23

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

我有一个集合,在mongodb数据库中存储有时间的孩子的出生日期。用户可以创建一个插槽,并根据该用户可以在该特定时隙中生成的子节点详细信息。例如,对于今天用户选择,08:00 AM - 09:30 AM,用户可以在屏幕上看到我能够成功完成的详细信息。

我无法获取不会在任何时间段落下的孩子的详细信息。例如,用户创建了4个插槽[08:00 AM - 09:30 AM,11:00 AM - 12:00,2:30 PM - 6:30 PM,09:00 PM - 09:30 PM],我想要获取在四个时段中任何一个都不属于的孩子的详细信息。

首先,我将检索插槽集合中的插槽,然后从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,但无法成功。

如果需要对上述任何细节进行更多说明,请与我们联系。

2 个答案:

答案 0 :(得分:1)

{{1}}

答案 1 :(得分:1)

我认为您的流程可以简化,并且可以一次性获得您想要的结果,而无需像您所说的那样“迭代”

假设我们使用问题中提到的四个插槽,我们正在寻找今天的结果。我会这样做,它将结果全部归类为:

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的帮助下,您可以在一次查询中获得所有结果。