Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从日期早于今天的数组聚合_Javascript_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

Javascript 从日期早于今天的数组聚合

Javascript 从日期早于今天的数组聚合,javascript,mongodb,mongodb-query,aggregation-framework,Javascript,Mongodb,Mongodb Query,Aggregation Framework,我正在尝试聚合具有数组的集合。在这个数组中,有一个提醒数组。文档可能如下所示: { _id: "1234", dates: { start: ISODate(), end: ISODate() }, reminders: [{ sendAt: ISODate(), status: 'closed' }, { sendAt: ISODate(), status: 'open' }] } 假设第一个在今天之前,下一个在今天之后

我正在尝试聚合具有数组的集合。在这个数组中,有一个
提醒
数组。文档可能如下所示:

{
  _id: "1234",
  dates: {
    start: ISODate(),
    end: ISODate()
  },
  reminders: [{
    sendAt: ISODate(),
    status: 'closed'
  }, {
    sendAt: ISODate(),
    status: 'open'
  }]
}
假设第一个在今天之前,下一个在今天之后。我想做的是获取今天之前所有的数组,或者,如果今天之前没有任何数组,则获取一个空数组。我尝试了以下方法

db.reminders.aggregate([
  { $match: { 'dates.end': { $gt: new Date } } },
  { $unwind: '$reminders' },
  {
    $match: {
      reminders: {
        $elemMatch: {
          sendAt: { $lt: new Date() },
          status: { $ne: 'open' }
        }
      }
    }
  }
])
然而,如果在今天之前没有提醒,它将失败,并且没有任何回报

有没有一种方法可以通过mongodb聚合来构建此结构

注意:我不能使用
$filter
,因为这是在3.2中的您可以使用操作符来筛选出版本
=2.6
的子文档。 它还避免了不必要的
$unwind
阶段

  • $match
    所有具有
    日期的文档。end
    属性大于搜索条件
  • $redact
    遍历所有子文档,并在符合条件的文档中执行以下操作,否则
示例代码:

var endDateToMatch = ISODate("2014-01-01T00:00:00Z");
var currentDate = ISODate();

db.t.aggregate([
{
  $match:{"dates.end":{$gt:endDateToMatch}}
},
{
  $redact:{$cond:[
                 {$and:[
                        {$ne:[{$ifNull:["$status",""]},
                              "open"]},
                        {$lt:[{$ifNull:["$sendAt",currentDate-1]},
                              currentDate]}
                       ]
                 },
                "$$DESCEND","$$PRUNE"]}
}
])
这将为每个与
$match
阶段匹配的文档提供一个文档。如果需要累加所有子文档,则需要通过
\u id
$unwind
“提醒”和
$group
作为
null

筛选出
=2.6版本的子文档。
它还避免了不必要的
$unwind
阶段

  • $match
    所有具有
    日期的文档。end
    属性大于搜索条件
  • $redact
    遍历所有子文档,并在符合条件的文档中执行以下操作,否则
示例代码:

var endDateToMatch = ISODate("2014-01-01T00:00:00Z");
var currentDate = ISODate();

db.t.aggregate([
{
  $match:{"dates.end":{$gt:endDateToMatch}}
},
{
  $redact:{$cond:[
                 {$and:[
                        {$ne:[{$ifNull:["$status",""]},
                              "open"]},
                        {$lt:[{$ifNull:["$sendAt",currentDate-1]},
                              currentDate]}
                       ]
                 },
                "$$DESCEND","$$PRUNE"]}
}
])

这将为每个与
$match
阶段匹配的文档提供一个文档。如果需要累积所有子文档,则需要通过
\u id
$diswind
$group
作为
null

,因此基本上需要
$filter
行为,但需要在早期版本中执行此操作,主案例是返回文档,即使数组内容最终为空

对于MongoDB 2.6,您可以使用和执行“几乎”相同的操作:

db.remements.aggregate([
{“$match”:{“dates.end”:{“$gt”:new Date()}},
{“$project”:{
“日期”:1,
“提醒”:{
“$setDifference”:[
{“$map”:{
“输入”:“$提醒”,
“作为”:“提醒”,
“在”:{
“$cond”:[
{“$and”:[
{“$lt”:[“$$remention.sendAt”,new Date()]},
{“$ne”:[“$$REMENTER.status”,“open”]}
]},
“$$提醒”,
假的
]
}
}},
[错误]
]
}
}}
])
只要从
$setDifference
得到的“set”都是不正确识别的项,这就可以了。因此,
$map
方法应用测试,如果条件不匹配,则返回内容或
false
$setdifference
基本上从结果中删除了任何
false
元素,但当然,作为一个“集合”,任何项的计数都与一项完全相同

如果您的MongoDB小于2.6(或者“集合”的情况使上述内容无法使用),那么在查看要过滤的内容时只需更加小心:

db.remements.aggregate([
{“$match”:{“dates.end”:{“$gt”:new Date()}},
{“$解除”:“$提醒”},
//计算条件匹配的位置
{“$组”:{
“\u id”:“$\u id”,
“日期”:{“$first”:“$dates”},
“提醒”:{“$push”:“$REMENTERS”},
“匹配”:{“$sum”:{
“$cond”:[
{“$and”:[
{“$lt”:[“$remements.sendAt”,new Date()]},
{“$ne”:[“$members.status”,“open”]}
]},
1.
0
]
}}
}},
//为简洁起见,替换不计数的数组
{“$project”:{
“日期”:1,
“提醒”:{“$cond”:[
{“$eq”:[“$matched”,0]},
{“$const”:[false]},
“$提醒”
]},
“匹配”:1
}},
//再次放松
{“$解除”:“$提醒”},
//筛选没有要保留的匹配项的“或”
{“$match”:{
“$or”:[
{ 
“remention.sendAt”:{“$lt”:new Date()},
“提醒.状态:{“$ne”:“打开”}
},
{“匹配”:0}
]
}},
//再次分组
{“$组”:{
“\u id”:“$\u id”,
“日期”:{“$first”:“$dates”},
“提醒”:{“$push”:“$REMENTERS”}
}},
//将[false]数组替换为空数组
{“$project”:{
“日期”:1,
“提醒”:{“$cond”:[
{“$eq”:[“$rementers”,[false]]},
{“$const”:[]},
“$提醒”
]}
}}
])
这有点冗长,但基本上是做同样的事情


还要注意的是,
$elemMatch
在处理
$unwind
后不适用,因为内容实际上不再是数组。简单的点表示法适用于现在单个文档中的元素。

因此您基本上想要
$filter
行为,但需要在早期版本中执行此操作,主要情况是返回文档,即使数组内容最终为空

对于MongoDB 2.6,您可以使用和执行“几乎”相同的操作:

db.remements.aggregate([
{“$match”:{“dates.end”:{”$