MongoDB查找查询:返回重复的记录,但具有唯一的现有ID
我有一份收集文件,上面写着测试:MongoDB查找查询:返回重复的记录,但具有唯一的现有ID,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一份收集文件,上面写着测试: {id: 123, lId: abc, cnum: [{num: 112, type:R}] }, {id: 234, lId: abc, cnum:[{ num: 112, type: R}] }, {id: 345, lId: cbd, cnum: [{num: 112, type: R}] }, {id: 456, lId: efg, cnum: [{num: 121, type:R}] } 我希望查询返回的值与cnum的num值重复,但
{id: 123,
lId: abc,
cnum: [{num: 112, type:R}]
},
{id: 234,
lId: abc,
cnum:[{ num: 112, type: R}]
},
{id: 345,
lId: cbd,
cnum: [{num: 112, type: R}]
},
{id: 456,
lId: efg,
cnum: [{num: 121, type:R}]
}
我希望查询返回的值与cnum的num值重复,但lId唯一。那就是它应该回来
id: 123,lId: abc, cnum.num: 112, id: 345,lId: cbd, cnum.num: 112
但目前它正在回归
id: 123,lId: abc,cnum.num: 112, id: 234, lId: abc, cnum.num: 112, id: 345,lId: cbd, cnum.num: 112
我当前的脚本也返回了重复的盖子。这是我的剧本:
var groupCnum = db.getCollection('test').aggregate([
{ $match: {"cnum.0": {$exists: true}}},
{ $unwind: "$cnum" },
{ $match: { "cnum.type": "R" } },
{ $group: { "_id": "$cnum.num", "count": { $sum: 1 } } },
{ $match: {"count": {"$gt": 1} } }
], {allowDiskUse: true}).map(record => record._id);
var duplicatedCnum = db.getCollection('test').aggregate([
{ $match: {"lId": {$nin: groupCnum}}},
{ $match: { "cnum.num": {$in: groupCnum} } },
{ $unwind: "$cnum" },
{ $match: { "cnum.type": "R" } },
{ $sort: {cnum: 1} },
{ $limit: 100}
], {allowDiskUse: true});
var fieldNames = ["id", "lId", "cnum.num"];
print(fieldNames.join(","));
有人能建议我缺少什么吗?您可以使用以下管道:
db.getCollection('test').aggregate([
{
$unwind: "$cnum"
},
{
$group: {
_id: "$cnum.num",
lId: {$addToSet: "$lId"},
doc: {$push: "$$ROOT"}
}
},
{
$match: {
"lId.0": {$exists: true}
}
},
{
"$unwind": "$doc"
},
{
$replaceRoot: {
newRoot: "$doc"
}
}
]);
请注意,对于此输入:
{id: 123, lId: abc, cnum: [{num: 112, type:R}, {num: 224, type: R}]}
{id: 124, lId: cdb, cnum: [{num: 112, type:R}]}
{id: 125, lId: xyz, cnum: [{num: 224, type:R}]}
您将收到以下输出:
{id: 123, lId: abc, cnum: {num: 112, type:R}}
{id: 123, lId: abc, cnum: {num: 224, type:R}}
{id: 124, lId: cdb, cnum: {num: 112, type:R}}
{id: 125, lId: xyz, cnum: {num: 224, type:R}}
因此,如果您想再次将
abc
分组,您应该在末尾再次将其添加到$group
。您可以使用以下管道:
db.getCollection('test').aggregate([
{
$unwind: "$cnum"
},
{
$group: {
_id: "$cnum.num",
lId: {$addToSet: "$lId"},
doc: {$push: "$$ROOT"}
}
},
{
$match: {
"lId.0": {$exists: true}
}
},
{
"$unwind": "$doc"
},
{
$replaceRoot: {
newRoot: "$doc"
}
}
]);
请注意,对于此输入:
{id: 123, lId: abc, cnum: [{num: 112, type:R}, {num: 224, type: R}]}
{id: 124, lId: cdb, cnum: [{num: 112, type:R}]}
{id: 125, lId: xyz, cnum: [{num: 224, type:R}]}
您将收到以下输出:
{id: 123, lId: abc, cnum: {num: 112, type:R}}
{id: 123, lId: abc, cnum: {num: 224, type:R}}
{id: 124, lId: cdb, cnum: {num: 112, type:R}}
{id: 125, lId: xyz, cnum: {num: 224, type:R}}
因此,如果您想再次分组
abc
,您应该在末尾再次将其添加到$group
。我可以通过以下查询获得所需的结果,以防它对某人有所帮助:
db.getCollection('test').aggregate([
{$match: {"cnum.0": { $exists: true }} },
{$unwind: "$cnum"},
{$match: { "cnum.type": "R"}},
{$group: {"_id": {"lId": "$lId", "cnum": "$cnum.num" } } },
{$group: {"_id": "$_id.cnum", "count": {$sum: 1}}},
{$match: {"count": {"$gt": 1}}
}])
我能够通过以下查询获得所需的结果,以防对某人有所帮助:
db.getCollection('test').aggregate([
{$match: {"cnum.0": { $exists: true }} },
{$unwind: "$cnum"},
{$match: { "cnum.type": "R"}},
{$group: {"_id": {"lId": "$lId", "cnum": "$cnum.num" } } },
{$group: {"_id": "$_id.cnum", "count": {$sum: 1}}},
{$match: {"count": {"$gt": 1}}
}])
您提供的示例文档中的类型与正在使用的查询(例如,来自查询
cnum
的查询)中的类型不匹配,似乎是一个数组。此外,我无法理解您如何从该聚合中获取这些返回类型,因为您没有对ltd
字段进行分组,所以我不确定到底发生了什么。如果你能把事情弄清楚up@TomSlabbaert是的,cnum是一个数组,很抱歉造成混淆,我已经更新了示例文档。我没有像上面那样得到返回值,它只是返回值的一个示例。为了清晰起见,我也对其进行了更新。另外,我不知道如何先按lId
分组,然后再按cnum
分组。也许这就是我不能正确得到的。你能解释一下为什么你不希望所有的文件都归还吗?看起来它们都和你的相配requirement@TomSlabbaert我的要求是获取重复的cnum
值,该值具有不同的lId
。因此,基本上如果两个唯一的lId
共享相同的cnum
。您提供的示例文档中的类型不匹配,并且您正在使用的查询(例如,来自查询cnum
的查询)似乎是一个数组。此外,我无法理解您如何从该聚合中获取这些返回类型,因为您没有对ltd
字段进行分组,所以我不确定到底发生了什么。如果你能把事情弄清楚up@TomSlabbaert是的,cnum是一个数组,很抱歉造成混淆,我已经更新了示例文档。我没有像上面那样得到返回值,它只是返回值的一个示例。为了清晰起见,我也对其进行了更新。另外,我不知道如何先按lId
分组,然后再按cnum
分组。也许这就是我不能正确得到的。你能解释一下为什么你不希望所有的文件都归还吗?看起来它们都和你的相配requirement@TomSlabbaert我的要求是获取重复的cnum
值,该值具有不同的lId
。所以基本上如果两个唯一的lId
共享相同的cnum
。