查询日期范围

时间:2014-07-04 07:31:26

标签: mongodb mongodb-query aggregation-framework

我有以下数据架构:

  {
      "Address" : "Test1",
      "City" : "London",
      "Country" : "UK",
      "Currency" : "",
      "Price_History" : {
         "2014-07-04T02:42:58" : [
            {
               "value1" : 98,
               "value2" : 98,
               "value3" : 98
            }
         ],
         "2014-07-04T03:50:50" : [
            {
                "value1" : 91,
               "value2" : 92,
               "value3" : 93
            }
         ]

      },
      "Location" : [
         9.3435,
         52.1014
      ],
      "Postal_code" : "xxx"
   }

如何在mongodb中生成查询以搜索“2014-07-04T02:42:58”“2014-07-04T03:50:50”<之间的所有结果/ strong>或如何生成查询以仅选择值 91 的结果,直到 93 > 才知道日期?

感谢

1 个答案:

答案 0 :(得分:1)

不是一个非常好的方法来模拟这个。一个更好的例子如下:

  {
      "Address" : "Test1",
      "City" : "London",
      "Country" : "UK",
      "Currency" : "",
      "Price_History" : [
          { "dateEnrty": 1, "date": ISODate("2014-07-04T02:42:58Z"), "value": 98 },
          { "dateEntry": 2, "date": ISODate("2014-07-04T02:42:58Z"), "value": 98 },
          { "dateEntry": 3, "date": ISODate("2014-07-04T02:42:58Z"), "value": 98 },
          { "dateEntry": 1, "date": ISODate("2014-07-04T03:50:50Z"), "value": 91 },
          { "dateEntry": 2, "date": ISODate("2014-07-04T03:50:50Z"), "value": 92 },
          { "dateEntry": 3, "date": ISODate("2014-07-04T03:50:50Z"), "value": 93 },
      ],
      "Location" : [
         9.3435,
         52.1014
      ],
      "Postal_code" : "xxx"
   }

或者那些不利用路径依赖的行。这里的查询相对简单,但也考虑到MongodDB搜索文档而不是数组这样的东西。但您可以使用聚合框架进行剖析:

db.collection.aggregate([

    // Still match first to reduce the possible documents
    { "$match": {
        "Price_History": {
            "$elemMatch": {
                "date": { 
                    "$gte": ISODate("2014-07-04T02:42:58Z"),
                    "$lte": ISODate("2014-07-04T03:50:50Z")
                },
                "value": 98
            }
        }
    }},

    // Unwind to "de-normalize"
    { "$unwind": "$Price_History" },

    // Match this time to "filter" the array which is now documents
    { "$match": {
        "Price_History.date": {
            "$gte": ISODate("2014-07-04T02:42:58Z"),
            "$lte": ISODate("2014-07-04T03:50:50Z")
        },
        "Price_Hisotry.value": 98
    }},

    // Now group back each document with the matches
    { "$group": {
        "_id": "$_id",
        "Address": { "$first": "$Address" },
        "City": { "$first": "$City" },
        "Country": { "$first": "$Country" },
        "Currency": { "$first": "$Currency" },
        "Price_History": { "$push": "$Price_History" },
        "Location": { "$first": "$Location" },
        "Postal_Code": { "$first": "$Postal_Code" }
    }}
])

或者更好地暂停“规范化”,只需选择您可以通过标准.find()处理的离散文档。必须更快更简单。

  {
      "Address" : "Test1",
      "City" : "London",
      "Country" : "UK",
      "Currency" : "",
      "date": ISODate("2014-07-04T02:42:58Z"),          
      "value": 98
  }

等。那么只需查询:

db.collection.find({
    "date": {
       "$gte": ISODate("2014-07-04T02:42:58Z"),
       "$lte": ISODate("2014-07-04T03:50:50Z")
    },
    "value": 98
})

我真的会将其作为“非规范化的”“Price History”集合,因为它更有效,基本上是聚合语句的模拟。

你要求的查询可以使用像MongoDB mapReduce那样评估JavaScript的东西,但正如我已经说过的那样,需要在没有任何索引帮助的情况下扫描整个集合,这很糟糕

将你的案子交给老板重新塑造并立即获得奖金。