设置查询中的MongoDB最新对象

时间:2013-10-18 14:28:59

标签: mongodb

我有一组日志数据对象,看起来像这样。

{
"_id" : ObjectId("52613da744aed3235450e6a9"),
"site" : "5-29",
"date" : ISODate("2013-10-18T10:41:17Z"),
"measures" : [
    [
        "Tank Lvl (ft)",
        6.923
    ],
    [
        "Internal Temp (C)",
        -5.6
    ],
    [
        "External Temp (C)",
        -8.1
    ],
    [
        "Batt (V)",
        12.65
    ],
    [
        "Well Press (psi)",
        31.905
    ]
]
}

每天很多时间,系统将收集更多数据。我正在尝试制定一个查询,该查询将返回特定网站特定日期的最新值。我可以在特定日期之后轻松询问特定网站的所有数据,但这样我每天都会全部记录。我只希望每个网站都有最新。例如:

鉴于以下收集:(忽略噪音......)

1. { "site" : "5-29",   "date" : ISODate("2013-10-18T10:41:17Z"), ....}
2. { "site" : "5-29",   "date" : ISODate("2013-10-18T10:42:17Z"), ....}
3. { "site" : "5-29",   "date" : ISODate("2013-10-18T10:43:17Z"), ....}
4. { "site" : "5-28",   "date" : ISODate("2013-10-18T10:41:17Z"), ....}
5. { "site" : "5-28",   "date" : ISODate("2013-10-18T10:42:17Z"), ....}
6. { "site" : "5-28",   "date" : ISODate("2013-10-18T10:43:17Z"), ....}

我希望查询只返回记录3和6,因为它们是该网站当天的最新条目。

2 个答案:

答案 0 :(得分:2)

你可以像这样运行查询

db.collection.find({ "site" : "5-29", "date" : ISODate("2013-10-18T10:41:17Z")}).sort({_id:-1}).limit(3);

它将返回"site" : "5-29",上创建的"date" : ISODate("2013-10-18T10:41:17Z")的最新三条记录。

因为mongodb创建的ObjectId包含这些部分

  1. 4字节值,表示自Unix纪元以来的秒数
  2. 3字节机器标识符
  3. 2字节进程ID,
  4. 3字节计数器,以随机值开头。
  5. 创建基于时间记录的_id排序记录排序。因此反向排序可以从表中获得最新结果。

答案 1 :(得分:2)

如果要查找每个站点的最新记录,请使用aggregation framework

db.collection.aggregate([
  {
    $match: { date: {
      $gt: new ISODate("2013-10-18T00:00:00Z"),
      $lt: new ISODate("2013-10-18T23:59:59Z") }
    }
  },
  {
    $sort: { date: 1 }
  },
  {
    $group: {
      _id: "$site",
      date: { $last: "$date" }
      // ... other document fields
    }
  }
]);
  • 首先,仅保留指定日期的记录
  • 然后按日期时间排序
  • 最后,按“网站”字段对记录进行分组记录,并从分组集中的最后文档中获取信息。