【问题标题】:Find latest data of a particular fields in mongoDB在 mongoDB 中查找特定字段的最新数据
【发布时间】:2019-12-25 11:52:03
【问题描述】:

我的 MongoDB 集合中的数据设置如下。我需要根据字段“eventType”找到最新的数据。

{
        "_id" : ObjectId("5d5690843248b8c20481f5e9"),
        "mrn" : "xp35",
        "eventType" : "LAB",
        "eventSubType" : "CBC",
        "value" : 1,
        "units" : 1,
        "charttime" : ISODate("2019-08-16T16:46:21.393Z")
}
{
        "_id" : ObjectId("5d5690843248b8c20481f5e9"),
        "mrn" : "xp35",
        "eventType" : "LAB",
        "eventSubType" : "CBB",
        "value" : 1,
        "units" : 1,
        "charttime" : ISODate("2019-08-16T16:46:22.393Z")
}
{
        "_id" : ObjectId("5d5690843248b8c20481f5ea"),
        "mrn" : "zfwy",
        "eventType" : "EDLIST",
        "eventSubType" : "Lipids",
        "value" : 1,
        "units" : 1,
        "charttime" : ISODate("2019-08-16T16:46:23.394Z")
}
{
        "_id" : ObjectId("5d5690843248b8c20481f5ea"),
        "mrn" : "zfwy",
        "eventType" : "EDLIST",
        "eventSubType" : "L",
        "value" : 1,
        "units" : 1,
        "charttime" : ISODate("2019-08-16T16:46:24.394Z")
}

我使用“聚合”和“查找”查询并根据时间戳字段“charttime”对其进行排序以获取最新数据,但它不起作用。我需要根据字段“eventType”获取数据,以便对于每个“eventType”我都应该得到最新的数据。所以在给定的例子中,我应该得到“LAB”和“EDLIST”的最新数据。理想情况下,它应该返回数据:

{
        "_id" : ObjectId("5d5690843248b8c20481f5e9"),
        "mrn" : "xp35",
        "eventType" : "LAB",
        "eventSubType" : "CBB",
        "value" : 1,
        "units" : 1,
        "charttime" : ISODate("2019-08-16T16:46:22.393Z")
}
{
        "_id" : ObjectId("5d5690843248b8c20481f5ea"),
        "mrn" : "zfwy",
        "eventType" : "EDLIST",
        "eventSubType" : "L",
        "value" : 1,
        "units" : 1,
        "charttime" : ISODate("2019-08-16T16:46:24.394Z")
}

【问题讨论】:

    标签: mongodb nosql mongodb-query aggregation-framework


    【解决方案1】:

    按照以下步骤操作:

    • 首先对所有文档进行排序。
    • eventtype分组。
    • 再次投影以将id 正确转换为_id (如果您对id 键没问题,则不需要)
    • 再次对这些数据进行排序(如果您可以使用不同的eventype 未按日期排序,则不需要)
    db.collection.aggregate([
      { $sort: {"charttime": 1 }},
      { $group: {
          _id: "$eventType",
          id: {$first: "$_id"},
          "mrn": {$first: "$mrn"},
          "eventType": {$first: "$eventType"},
          "eventSubType": {$first: "$eventSubType"},
          "value": {$first: "$value"},
          "units": {$first: "$units"},
          "charttime": {$first: "$charttime"}
      }},
      {$project: {
          _id: "$id",
          "mrn": 1,
          "eventType": 1,
          "eventSubType": 1,
          "value": 1,
          "units": 1,
          "charttime": 1
      }},
      { $sort: {"charttime": 1 }}
    ])
    

    希望对您有所帮助!

    输出:

    /* 1 */
    {
        "_id" : ObjectId("5d5cedb1fc18699f18a24fa2"),
        "mrn" : "xp35",
        "eventType" : "LAB",
        "eventSubType" : "CBB",
        "value" : 1,
        "units" : 1,
        "charttime" : ISODate("2019-08-16T16:46:22.393Z")
    }
    
    /* 2 */
    {
        "_id" : ObjectId("5d5cedc1fc18699f18a24fa9"),
        "mrn" : "zfwy",
        "eventType" : "EDLIST",
        "eventSubType" : "L",
        "value" : 1,
        "units" : 1,
        "charttime" : ISODate("2019-08-16T16:46:24.394Z")
    }
    

    ===== 更新 =====

    根据您的要求优化查询:

    db.collection.aggregate([
      { $sort: {"charttime": -1 }}, // Sort in descending. (So we would not have another sort after group)
      { $group: { 
          _id: "$eventType", // Group by event type
          data: {$first: "$$ROOT"} // Take whole first record
      }},
      { $replaceRoot: { newRoot: "$data" }} // Replaceroot to have document as per your requirement
    ])
    

    ===== 更新 2 ====

    记录太多: - 查找事件类型和最大图表时间 - 迭代每个文档并获取记录(您可能在 DB 上进行了多次调用,但会花费更少的时间)

    db.getCollection('Vehicle').aggregate([
      { $group: { 
          _id: "$eventType", // Group by event type
          maxChartTime: {$max: "$charttime"}
      }}
    ]).forEach(function(data) {
        db.getCollection('Vehicle').find({
          "eventType": data._id,
          "charttime": data.maxChartTime
        });
        // Any mechanism to have array of all retrieved documents.
        // You can handle it from your back end too.
    })
    

    注意:- 我已经用506983 记录对其进行了测试,并在0.526 秒内得到了结果。

    【讨论】:

    • 谢谢!!!!我们可以优化这个解决方案吗?就像在 $group 和 $project 中一样,您已经添加了每个字段。有没有其他方法可以包含所有字段?
    • 我使用的是 mongoDB 3.2 我相信它不支持'$replaceRoot'
    • @RunSmeagolRun,然后您需要在每个字段中使用$project,或者不使用任何内容。您可以从后端代码处理它以迭代 document.data 以获取所有文档。
    • 我的集合中有 10,000,000 条记录,聚合花费了太多时间。您能否提出其他解决方案?
    【解决方案2】:
    • 首先按charttime 对数据进行排序(降序),这样$first 蓄能器工作正常。
    • 然后按eventType 分组并查找最新的日期 $maxaccumulator。
    • $project管道是保留原来的_id同键 名称字段。如果不需要_id,您可以移除管道 完全一致。

    聚合查询:

    db.collection.aggregate([
      { $sort: { charttime: -1 } },
      {
        $group: {
          _id: "$eventType",
          id: { $first: "$_id" },
          mrn: { $first: "$mrn" },
          eventType: { $first: "$eventType" },
          eventSubType: { $first: "$eventSubType" },
          value: { $first: "$value" },
          units: { $first: "$units" },
          charttime: { $max: "$charttime" }
        }
      },
      {
        $project: {
          _id: "$id",
          mrn: 1,
          eventType: 1,
          eventSubType: 1,
          value: 1,
          units: 1,
          charttime: 1
        }
      }
    ]);
    

    【讨论】:

      猜你喜欢
      • 2021-11-10
      • 1970-01-01
      • 2017-12-15
      • 2016-07-29
      • 1970-01-01
      • 1970-01-01
      • 2021-03-06
      • 2014-07-17
      • 1970-01-01
      相关资源
      最近更新 更多