匹配$ gte $ lte中所有数组元素的文档

时间:2016-04-20 10:58:33

标签: mongodb mongodb-query aggregation-framework

以下是我的示例文档:

{
updated: [
    1461062102,
    1461062316
],
name: "test1",
etc: "etc"
}

{
updated: [
    1460965492,
    1461060275
],
name: "test2",
etc: "etc"
}


{
updated: [
    1461084505
],
name: "test3",
etc: "etc"
}

{
updated: [
    1461060430
],
name: "test4",
etc: "etc"
}

{
updated: [
    1460965715,
    1461060998
],
name: "test5",
etc: "etc"
}

查找查询的正确用法是在$gte$lte条件中获取与更新日期匹配的所有文档吗?

例如

db.test.find({'updated':{$elemMatch:{$gte:1461013201,$lte:1461099599}}})

我可以使用$或将其设置为updated.0:{$gte:1461013201,$lte:1461099599}update.1:{$gte:1461013201,$lte:1461099599}等,但如果我的数组包含更多更新的日期会怎样?

据我所知,$ elemMatch并不是'符合我的标准,因为它只匹配数组中的第一个出现。

1 个答案:

答案 0 :(得分:2)

好问题。您使用$elemMatch走在了正确的轨道上,但这确实采用了标准运营商未涵盖的其他逻辑。

所以你要么做$redact

db.test.aggregate([
  { "$match": {
    'updated': { '$elemMatch':{ '$gte':1461013201, '$lte':1461099599 } }
  }},
  { "$redact": {
    "$cond": {
      "if": { 
        "$allElementsTrue": {
          "$map": {
            "input": "$updated",
            "as": "upd",
            "in": {
              "$and": [
                { "$gte": [ "$$upd", 1461013201 ] },
                { "$lte": [ "$$upd", 1461099599 ] }
              ]
            }
          }
        }
      },
      "then": "$$KEEP",
      "else": "$$PRUNE"
    }
  }}
])

或者在早于MongoDB 2.6的版本中,使用$where子句处理:

db.test.find({
  'updated': { '$elemMatch':{ '$gte':1461013201, '$lte':1461099599 } },
  "$where": function() {
    return this.updated.filter(function(el) { 
      return el >= 1461013201 &&  el <= 1461099599;
    }).length == this.updated.length;
  }
})

问题在于,尽管一般的原生“查询”操作符可以告诉您一个数组成员符合条件,但它无法告诉您所有它们都符合条件。

因此,可以使用$map$allElementsTrue来测试条件,这些都可以从MongoDB 2.6获得。使用MongoDB 3.2,$filter$size等同于以下JavaScript测试。

或者您可以使用$where的JavaScript评估来测试与原始数据相关的“已过滤”数组长度,并看到它们仍然相同。

这是为了让所有与所提供的范围条件相匹配而构建的额外逻辑。聚合方法是本机代码,而不是JavaScript解释。相比之下,它可以更快地运行更多

但是你仍然希望在所有情况下都保留$elemMatch

当然,这里有匹配的文件:

{
        "updated" : [
                1461062102,
                1461062316
        ],
        "name" : "test1",
        "etc" : "etc"
}
{
        "updated" : [
                1461084505
        ],
        "name" : "test3",
        "etc" : "etc"
}
{
        "updated" : [
                1461060430
        ],
        "name" : "test4",
        "etc" : "etc"
}