使用特定排序消除 MongoDB 中的重复项
Eliminate duplicates in MongoDB with a specific sort
我有一个由与工作合同相对应的条目组成的数据库。在 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
}
]
}
从原来的table一些合同已经过双重检查,因此我只需要保留一个。更具体地说(在示例中),我认为这些合同(针对同一工人)是在同一天与同一雇主签订的,这些合同是重复的。但是,应该正确选择保留哪些副本,哪些不保留(这不取决于我)。实质上,有一个名为 '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) 方法进行心理转换的阶段。为这个愚蠢的问题道歉。
如果按ord_id
反向排序,可以在$group
阶段使用$first
到select最高值。此示例将 return 整个文档 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})
此聚合将 return 期望的结果 - 消除基于 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"
}
}
] )
我有一个由与工作合同相对应的条目组成的数据库。在 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
}
]
}
从原来的table一些合同已经过双重检查,因此我只需要保留一个。更具体地说(在示例中),我认为这些合同(针对同一工人)是在同一天与同一雇主签订的,这些合同是重复的。但是,应该正确选择保留哪些副本,哪些不保留(这不取决于我)。实质上,有一个名为 '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) 方法进行心理转换的阶段。为这个愚蠢的问题道歉。
如果按ord_id
反向排序,可以在$group
阶段使用$first
到select最高值。此示例将 return 整个文档 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})
此聚合将 return 期望的结果 - 消除基于 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"
}
}
] )