【问题标题】:Eliminate duplicates in MongoDB with a specific sort使用特定排序消除 MongoDB 中的重复项
【发布时间】:2020-08-13 22:15:32
【问题描述】:

我有一个由对应于工作合同的条目组成的数据库。在我由特定工作人员聚合的 MongoDB 数据库中,数据库 - 在简化版本中 - 看起来像这样。

{
    "_id" : ObjectId("5ea995662a40c63b14266071"),
    "worker" : "1070",
    "employer" : "2116096",
    "start" : ISODate("2018-01-11T01:00:00.000+01:00"),
    "ord_id" : 0
},
{
    "_id" : ObjectId("5ea995662a40c63b14266071"),
    "worker" : "1070",
    "employer" : "2116096",
    "start" : ISODate("2018-01-11T01:00:00.000+01:00"),
    "ord_id" : 1
},
{
    "_id" : ObjectId("5ea995662a40c63b14266072"),
    "worker" : "1071",
    "employer" : "2116055",
    "start" : ISODate("2019-01-03T01:00:00.000+01:00"),
    "ord_id" : 2
},
{
    "_id" : ObjectId("5ea995662a40c63b14266072"),
    "worker" : "1071",
    "employer" : "2116056",
    "start" : ISODate("2019-01-03T01:00:00.000+01:00"),
    "ord_id" : 3
},

我已经根据工人重新安排了

{
    "_id" : ObjectId("5ea995662a40c63b14266071"),
    "worker" : "1070",
    "contratcs" : [
             {
               "employer" : "2116096",
               "start" : ISODate("2018-01-11T01:00:00.000+01:00"),
               "ord_id" : 0
             },
             {
               "employer" : "2116096",  
               "start" : ISODate("2018-01-11T01:00:00.000+01:00"),
               "ord_id" : 1
             } // Since employer identification and starting date is the same of the previous, this is a duplicate!
         ]
},
{
    "_id" : ObjectId("5ea995662a40c63b14266072"),
    "worker" : "1701",
    "contratcs" : [
             {
               "employer" : "2116055",
               "start" : ISODate("2019-01-03T01:00:00.000+01:00"),
               "ord_id" : 2
             },
             {
               "employer" : "2116056",
               "start" : ISODate("2019-01-04T01:00:00.000+01:00"),
               "ord_id" : 3
             }
         ]
}

从原始表格中,一些合同已被双重检查,因此我只需要保留一个。更具体地说(在示例中),我认为与同一雇主在同一天开始的那些合同(针对同一工人)重复。但是,应该正确选择哪些重复保留,哪些不保留(这不取决于我)。基本上,有一个名为“ord_id”的字段(我已经生成了将数据库生成到 MongoDB 中),它是一个数字并且是唯一的(因此,在重复项中,它是唯一实际不同的术语)。基本上,我必须在重复项中保留“ord_id”值最高的那些。通过关注this 线程我写道:

db.mycollection.aggregate([
    { $unwind: "$contracts" },
    { $group: {
        _id: { WORKER: "$worker", START: "$contracts.start" },
        dups: { $addToSet: "$_id" },
        ord_id: { $addToSet: "$contracts.ord_id" },
        count:  {$sum: 1 }
        }
    },
    { $match: { count: { $gt: 1} } },
    { $sort: {count: -1, ord_id: -1 } }
],{allowDiskUse: true}).
forEach(function(doc) {
    doc.dups.shift();     
    db.mycollection.remove({_id : {$in: doc.dups }});  
});

尽管我在按合同汇总时遇到了消除问题,但我想将重复项转移(然后保留)具有最高值“ord_id”的重复项。 我还是 MongoDB 的新手,并且仍处于从主要是关系 (SQL) 方法的心理转换阶段。为这个愚蠢的问题道歉。

【问题讨论】:

    标签: mongodb drop-duplicates


    【解决方案1】:

    此聚合将返回所需的结果 - 根据 worker+employer+start contracts 消除重复项,并仅保留具有最高 ord_id 的合同(在重复项中)。

    db.collection.aggregate( [
      { 
          $unwind: "$contracts" 
      },
      { 
          $group: { 
               _id: { worker: "$worker", employer: "$contracts.employer", start: "$contracts.start" },
               max_ord: { $max: "$contracts.ord_id" },
               doc: { $first: "$$ROOT" }
          } 
      },
      { 
          $group: {
              _id: { _id: "$doc._id", worker: "$doc.worker" },
              contracts: { $push: { employer: "$_id.employer", start: "$_id.start", ord_id: "$ords" } }
          }
      },
      { 
          $addFields: {
              _id: "$_id._id", 
              worker: "$_id.worker"
          }
      } 
    ] )
    

    【讨论】:

    • 我已经根据我的需要稍微调整了代码,它工作正常,谢谢!
    【解决方案2】:

    如果您按ord_id 反向排序,则可以在$group 阶段使用$first 来选择最高值。此示例将返回doc 中的整个文档,以及重复次数:

    db.mycollection.aggregate([
        { $unwind: "$contracts" },
        { $sort: {"$contracts.ord_id":-1}},
        { $group: {
            _id: { WORKER: "$worker", START: "$contracts.start", EMPLOYER: "$contracts.employer" },
            doc: { $first: "$$ROOT" },
            count:  {$sum: 1 }
        }}
    ],{allowDiskUse: true})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      • 2018-02-15
      • 2022-01-19
      • 1970-01-01
      • 2015-11-16
      • 1970-01-01
      • 2019-03-25
      相关资源
      最近更新 更多