消除MongoDB中具有特定排序的重复项
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消除MongoDB中具有特定排序的重复项相关的知识,希望对你有一定的参考价值。
我有一个由与工作合同相对应的条目组成的数据库。在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)方法的思维转变阶段。对这个愚蠢的问题表示歉意。
答案
如果按ord_id
进行反向排序,则可以在$first
阶段使用$group
选择最大值。此示例将返回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)
另一答案
此聚合将返回期望的结果-消除基于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中具有特定排序的重复项的主要内容,如果未能解决你的问题,请参考以下文章