MongoDB:获取具有两个值的不同组合的最新文档

Posted

技术标签:

【中文标题】MongoDB:获取具有两个值的不同组合的最新文档【英文标题】:MongoDB: Get newest documents with distinct combination of two values 【发布时间】:2021-12-27 10:04:40 【问题描述】:

所以我有一个问题,如何对数据库形成一个稍微复杂的特定查询。 我有一个包含类似文档的集合:

[
  "_id":  "$oid" : "Object1" ,
  "created":  "$date" : "2021-11-14T10:58:01.456Z" ,
  "primaryId": "SomeId1",
  "secondaryIdx": 0,
  "otherData" : something


  "_id":  "$oid" : "Object2" ,
  "created":  "$date" : "2021-11-13T10:58:01.456Z" ,
  "primaryId": "SomeId2",
  "secondaryIdx": 0,
  "otherData" : something


  "_id":  "$oid" : "Object3" ,
  "created":  "$date" : "2021-11-15T10:58:01.456Z" ,
  "primaryId": "SomeId2",
  "secondaryIdx": 1,
  "otherData" : something


  "_id":  "$oid" : "Object4" ,
  "created":  "$date" : "2021-11-16T10:58:01.456Z" ,
  "primaryId": "SomeId1",
  "secondaryIdx": 0,
  "otherData" : something
]

我生成的集合应该只有具有primaryId + secondaryIdx 唯一组合的文档。只要有一个以上的文件与这种组合,我只想得到最新的一个。 所以我的结果应该是这样的:


  "_id":  "$oid" : "Object2" ,
  "created":  "$date" : "2021-11-13T10:58:01.456Z" ,
  "primaryId": "SomeId2",
  "secondaryIdx": 0,
  "otherData" : something


  "_id":  "$oid" : "Object3" ,
  "created":  "$date" : "2021-11-15T10:58:01.456Z" ,
  "primaryId": "SomeId2",
  "secondaryIdx": 1,
  "otherData" : something


  "_id":  "$oid" : "Object4" ,
  "created":  "$date" : "2021-11-16T10:58:01.456Z" ,
  "primaryId": "SomeId1",
  "secondaryIdx": 0,
  "otherData" : something
]

所以 Object1 被排除在结果之外,因为 primaryId+secondaryIdx 是重复的,而 Object4 是较新的。

我目前在我的应用程序中实现了此功能,但我认为在查询级别执行此操作会更好,因此我的应用程序不必加载不必要的大集合,然后必须过滤掉其中的大部分反正马上。

【问题讨论】:

【参考方案1】:

您可以先通过$sort primaryId: 1, secondaryIdx: 1, created: -1。然后在primaryId + secondaryIdx 旁边做一个$group 然后取第一个文件。

db.collection.aggregate([
  
    $sort: 
      primaryId: 1,
      secondaryIdx: 1,
      created: -1
    
  ,
  
    $group: 
      _id: 
        primaryId: "$primaryId",
        secondaryIdx: "$secondaryIdx"
      ,
      lastDoc: 
        $first: "$$ROOT"
      
    
  ,
  
    "$replaceRoot": 
      "newRoot": "$lastDoc"
    
  
])

这里是Mongo playground 供您参考。

【讨论】:

按primaryId和secondaryIdx排序有什么原因吗?只需创建日期即可获得预期的输出。 实际上排序不是强制性的,但根据我过去的经验,通常你的用例会得到像primaryId: 1, secondaryIdx: 1, created: -1 这样的复合索引的帮助,因为你正在进行分组操作。如果您也从此类索引的存在中受益,您可能也想利用该索引。 所以如果有一个带有primaryId: 1, secondaryIdx: 1, created: -1的复合索引,而不是一个只有created: -1的复合索引,那么按所有字段排序(即使没有必要)是否更有效索引? 是的,你是对的。您可以参考this official MongoDB document了解更多信息。 谢谢,这似乎正是我所需要的。

以上是关于MongoDB:获取具有两个值的不同组合的最新文档的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB查询以获取与具有多个值的键匹配的所有文档[重复]

组合两个查询集,具有不同值的公共字段

合并具有来自两个不同列的匹配值的 DataFrame - Pandas [重复]

MongoDB $查找具有不同值的对象数组

MongoDB聚合在Java中具有不同的价值?

MongoDB:获取不同数据模型的最新 10 项?