【问题标题】:MongoDB find query: return duplicate records but which has unique existing idsMongoDB查找查询:返回重复记录但具有唯一的现有ID
【发布时间】:2020-05-27 17:54:06
【问题描述】:

我有一个收集文件说测试:

{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

我当前的脚本也返回了重复的 lId。这是我的脚本:

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(","));

谁能建议我错过了什么?

【问题讨论】:

  • 您提供的示例文档和您正在使用的查询中的类型不匹配,例如来自查询cnum 的查询似乎是一个数组。另外,您如何从该聚合中获取这些返回类型超出了我的范围,因为您没有对 ltd 字段进行分组,所以我不确定发生了什么。如果你能把事情弄清楚
  • @TomSlabbaert 是的,cnum 是一个数组,很抱歉造成混淆,我已经更新了示例文档。我没有得到上面的返回值,它只是返回值的一个示例。为了清楚起见,我也更新了它。我也不确定如何先按lId 分组,然后按cnum 分组。可能这就是我无法正确理解的。
  • 你能解释一下为什么你不希望所有的文件都归还吗?好像都符合你的要求
  • @TomSlabbaert 我的要求是获取具有不同lId 的重复cnum 值。所以基本上如果 2 个独特的 lId 共享相同的 cnum

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

您可以使用以下管道:

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

【讨论】:

    【解决方案2】:

    如果对某人有帮助,我可以通过以下查询获得所需的结果:

    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}}
    }])
    

    【讨论】:

      猜你喜欢
      • 2012-08-04
      • 1970-01-01
      • 2021-06-14
      • 1970-01-01
      • 2015-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-28
      相关资源
      最近更新 更多