Javascript 在同一查询中使用distinct和limit的MongoDB查询

Javascript 在同一查询中使用distinct和limit的MongoDB查询,javascript,mongodb,mongodb-query,aggregation-framework,Javascript,Mongodb,Mongodb Query,Aggregation Framework,我试图从MongoDb文档返回应用程序中每个设备的最新读数 我可以通过查询返回整个应用程序的最新读数,但不能返回应用程序中每个单独设备的最新读数 这是集合中文档的结构: { _id: 5f456ab2e836990e5e7d9550, appID: 'helen-app', deviceID: 'eleanor-house', time: 'Tue Aug 25 2020 20:46:58 GMT+0100 (British Summer Time)',

我试图从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)
      });
我使用了distinct collection方法,该方法收集与应用程序关联的所有设备,但我无法循环每个设备以获取最新的读数,我觉得在一个查询中完成所有操作会更有效

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

您需要实现以下目标:

查询:

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
    }
  ])
测试:

注意:

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
    }
  ])
数据库中的日期始终采用
Date
格式,但不采用字符串格式,最好在集合的所有文档中至少维护一个日期字段。不要忘记创建索引,并使用
.explain()
检查您的查询是否有效地使用了索引

JFYI-如果您的集合太大,无法对字段进行排序,那么这种操作也可以通过自动创建的
\u id
字段来实现,因为MongoDB中的字段也可以表示日期,加上是自动索引的,速度足够快,最后,这一切都取决于您的应用程序,如何使用数据库,即;写入数据库。

您需要实现以下目标:

查询:

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
    }
  ])
测试:

注意:

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
    }
  ])
数据库中的日期始终采用
Date
格式,但不采用字符串格式,最好在集合的所有文档中至少维护一个日期字段。不要忘记创建索引,并使用
.explain()
检查您的查询是否有效地使用了索引


JFYI-如果您的集合太大,无法对字段进行排序,那么这种操作也可以通过自动创建的
\u id
字段来实现,因为MongoDB中的字段也可以表示日期,加上是自动索引的,速度足够快,最后,这一切都取决于您的应用程序,如何使用数据库,即;写信给DB。

我的第一个想法是你的查询很奇怪。如果您想要排序和限制,通常我看到它遵循以下模式:
col.find({appID:user.appID}).sort({time:-1}).limit(1)
。根据我的经验,
find()
中的第二个
{}
通常是投影参数。@Taplar谢谢!!我稍微编辑了一下代码。最后我省略了
.limit()
,因为我相信这会将整个查询限制为一个文档,而不会返回每个设备的最新读数。你认为会有一种方法在投影参数中把相似的东西和不同的特性放在一起吗?我的第一个想法是你的查询很奇怪。如果您想要排序和限制,通常我看到它遵循以下模式:
col.find({appID:user.appID}).sort({time:-1}).limit(1)
。根据我的经验,
find()
中的第二个
{}
通常是投影参数。@Taplar谢谢!!我稍微编辑了一下代码。最后我省略了
.limit()
,因为我相信这会将整个查询限制为一个文档,而不会返回每个设备的最新读数。你认为会有一种方法在投影参数中把相似的东西和不同的特性放在一起吗?你只不过是一个传奇!!!!非常感谢你!!!!解决了我的问题!!顺便说一句,我现在在我论文的致谢信中提到你@海伦·约翰逊:嘿,别担心,这只是社区中大多数人每天都会做的基本帮助。忘了它吧,一切都很顺利,很高兴听到&愉快的编码:-)你只不过是一个传奇!!!!非常感谢你!!!!解决了我的问题!!顺便说一句,我现在在我论文的致谢信中提到你@海伦·约翰逊:嘿,别担心,这只是社区中大多数人每天都会做的基本帮助。忘了它吧,一切正常,很高兴听到&愉快地编码:-)