【问题标题】:MongoDB query using distinct and limit in the same queryMongoDB 查询在同一查询中使用 distinct 和 limit
【发布时间】:2020-08-25 20:23:00
【问题描述】:

我正在尝试从 MongoDb 文档中返回应用程序中每个设备的最新读数。

我可以让查询返回整个应用程序的最新读数,但不能返回应用程序中每个单独设备的最新读数。

这是集合中文档的结构:

  {
    _id: 5f456ab2e836990e5e7d9550,
    appID: 'helen-app',
    deviceID: 'eleanor-house',
    time: 'Tue Aug 25 2020 20:46:58 GMT+0100 (British Summer Time)',
    payload: { type: 'Feature', properties: [Object], geometry: [Object] }
  }

一个应用程序中有多个设备。

这是当前返回整个应用程序的最新读数的查询,按 deviceID 和时间顺序分组:

  col.find({ appID: user.appID }).sort({deviceID: 1, time: -1}).toArray(function(err,res){
        console.log(res)
      });

我使用了独特的收集方法,它收集与应用程序关联的所有设备,但我无法遍历每个设备以获取最新读数,我觉得在一个查询中完成所有操作会更有效。

有没有办法将独特的功能合并到上面的查询中,以便为每个设备选择最新读数,而不仅仅是整个应用程序?

【问题讨论】:

  • 我的第一个想法是你的查询很奇怪。如果您想排序和限制,通常我已经看到它遵循以下模式:col.find({ appID: user.appID }).sort({ time: -1 }).limit(1)find() 中的第二个 {} 通常是我的经验中的投影参数。
  • @Taplar 谢谢!!我稍微编辑了代码。我在最后省略了.limit(),因为我相信这会将整个查询限制为 1 个文档,该文档不会返回每个设备的最新读数。您认为有办法将与投影参数中的独特特征相似的东西放在一起吗?

标签: javascript mongodb mongodb-query aggregation-framework


【解决方案1】:

您需要aggregation-pipeline 来实现这一点:

查询:

db.collection.aggregate([
    {
      "$match": { appID: "helen-app" } // filter docs based on appID
    },
    {
      $sort: { time: -1 } // sort in descending order
    },
    {
      $group: { _id: "$deviceID", doc: { $first: "$$ROOT" } } // group on `deviceID` field and push first document into `doc` field
    },
    {
      "$replaceRoot": { "newRoot": "$doc" } // make `doc` field as new root to each document
    }
  ])

测试: mongoplayground

注意:

DB 中的日期始终为Date 格式,但不是字符串格式,最好在集合的所有文档中至少保留一个日期字段。不要忘记创建索引并使用.explain() 来检查您的查询是否有效地使用了索引。

JFYI - 如果您的集合太大而无法按字段排序,那么这种操作也可以通过自动创建的 _id 字段来实现,因为 MongoDB 中的该字段可以表示日期以及加上自动索引并且足够快,最后,这完全取决于您的应用程序,它如何使用数据库,即;写入数据库。

【讨论】:

  • 你不过是个传奇!!!!非常感谢!!!!解决了我的问题!
  • 顺便说一下,我现在在我的论文致谢中提到你!
  • @HelenJohnson:嘿,没关系,这只是社区中大多数人每天都会做的基本帮助。忘记它,一切正常,很高兴听到和快乐的编码:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 1970-01-01
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
  • 2011-06-27
  • 1970-01-01
相关资源
最近更新 更多