当前位置: 首页 > 知识库问答 >
问题:

使用数组字段的元素对mongo文档进行分组

颜修为
2023-03-14

我有以下 3 份文件。每个代表一个用户的联系人:

{ 
    "_id" : ObjectId("57f9f9f3b91d070315273d0d"), 
    "profileId" : "test", 
    "displayName" : "duplicateTest", 
    "email" : [
        {
            "emailId" : "a@a.com"
        }, 
        {
            "emailId" : "b@b.com"
        }, 
        {
            "emailId" : "c@c.com"
        }
    ]
}
{ 
    "_id" : ObjectId("57f9fab2b91d070315273d11"), 
    "profileId" : "test", 
    "displayName" : "duplicateTest2", 
    "email" : [
        {
            "emailId" : "a@a.com"
        }
    ]
}
{ 
    "_id" : ObjectId("57f9fcefb91d070315273d15"), 
    "profileId" : "test", 
    "displayName" : "duplicateTest2", 
    "email" : [
        {
            "emailId" : "b@b.com"
        }
    ]
}

我需要通过数组元素对它们进行聚合/分组,这样我就可以识别重复的联系人(基于电子邮件id)。因为在文档(1

我尝试在java中使用$unwind和$group执行此操作,如下所示:

List<DBObject> aggList = new ArrayList<DBObject>();

        BasicDBObject dbo = new BasicDBObject("$match", new BasicDBObject("profileId", "0fb72dcf-292b-4343-a0e7-1d613a803b1e"));

        aggList.add(dbo);

        BasicDBObject dboUnwind = new BasicDBObject("$unwind", "$email");
        aggList.add(dboUnwind);



        BasicDBObject dboGroup = new BasicDBObject("$group",
                new BasicDBObject().append("_id", new BasicDBObject("name", "$email.emailId"))
                        .append("uniqueIds", new BasicDBObject("$addToSet", "$_id"))
                        .append("count", new BasicDBObject("$sum", 1)));

        aggList.add(dboGroup);

        BasicDBObject dboCount = new BasicDBObject("$match", new BasicDBObject("count", new BasicDBObject("$gte", 2)));
        aggList.add(dboCount);


        BasicDBObject dboSort = new BasicDBObject("$sort", new BasicDBObject("count",-1));
        aggList.add(dboSort);


        BasicDBObject dboLimit = new BasicDBObject("$limit", 10);
        aggList.add(dboLimit);


        AggregationOutput output = collection.aggregate(aggList);


    System.out.println(output.results());

这按电子邮件ID对文档进行分组(这是正确的),但没有达到目的。

任何帮助都将不胜感激。

我需要实现的功能,用户可以在他的存储库可能重复的联系人提示。我需要聚合结果类似于:

[  
   {  
      "_id":{  
         "name":[  
            {
            "emailId" : "a@a.com"
        }, 
        {
            "emailId" : "b@b.com"
        }, 
        {
            "emailId" : "c@c.com"
        }
         ]
      },
      "uniqueIds":[  
         {  
            "$oid":"57f9fcefb91d070315273d15"
         },
 {  
            "$oid":"57f9fcefb91d070315273d11"
         },
 {  
            "$oid":"57f9fcefb91d070315273d15"
         }
      ],
      "count":3
   },

所以,基本上,我需要所有可能的重复联系人的_id(可能还有另一组重复联系人,上面有_id列表),以便我可以提示用户,用户可以随意合并它们。希望现在更清楚。谢谢

共有1个答案

湛光明
2023-03-14

好吧,您的问题与您寻求的结果略有不同。您最初的问题向我指出了以下聚合:

db.table.aggregate(
  [
    {
      $unwind: "$email"
    },
    {
      $group: {
      _id : "$email.emailId",
      duplicates : { $addToSet : "$_id"}
      }
    }
  ]
);

这导致:

{ 
    "_id" : "c@c.com", 
    "duplicates" : [
        ObjectId("57f9f9f3b91d070315273d0d")
    ]
}
{ 
    "_id" : "b@b.com", 
    "duplicates" : [
        ObjectId("57f9fcefb91d070315273d15"), 
        ObjectId("57f9f9f3b91d070315273d0d")
    ]
}
{ 
    "_id" : "a@a.com", 
    "duplicates" : [
        ObjectId("57f9fab2b91d070315273d11"), 
        ObjectId("57f9f9f3b91d070315273d0d")
    ]
}

按邮件分组。

但是您添加到问题中的示例输出进行了汇总:

db.table.aggregate(
  [
    {
      $unwind: "$email"
    },
    {
      $group: {
      _id : "$profileId",
      emails : { $addToSet : "$email.emailId"},
      duplicates : { $addToSet : "$_id"}
      }
    }
  ]
);

这导致:

{ 
    "_id" : "test", 
    "emails" : [
        "c@c.com", 
        "b@b.com", 
        "a@a.com"
    ], 
    "duplicates" : [
        ObjectId("57f9fcefb91d070315273d15"), 
        ObjectId("57f9fab2b91d070315273d11"), 
        ObjectId("57f9f9f3b91d070315273d0d")
    ]
}
 类似资料:
  • 我需要在颠簸转换规范方面的帮助。以下是我到目前为止的工作。 输入: 使用的震动代码: 电流输出: 预期产出 当只使用单个json对象时,此代码工作正常。但是当我们使用具有相同id的多个项目时,它会开始对所有相关字段进行分组。

  • 主要内容:算法总结及实现,优化算法在实际开发中,有很多场景需要我们将数组元素按照从大到小(或者从小到大)的顺序排列,这样在查阅数据时会更加直观,例如: 一个保存了班级学号的数组,排序后更容易分区好学生和坏学生; 一个保存了商品单价的数组,排序后更容易看出它们的性价比。 对数组元素进行排序的方法有很多种,比如冒泡排序、归并排序、选择排序、插入排序、快速排序等,其中最经典最需要掌握的是「冒泡排序」。 以从小到大排序为例,冒泡排序的整体

  • 本文向大家介绍使用 JavaScript 对数组元素进行深度计数,包括了使用 JavaScript 对数组元素进行深度计数的使用技巧和注意事项,需要的朋友参考一下 问题 我们需要编写一个JavaScript函数,该函数接受元素的嵌套数组并返回该数组中存在的元素的深层计数。 输入 输出 由于级别1的元素为2,级别2的元素为2,级别3的元素为1,因此深度计数为7。 示例 以下是代码- 代码说明 我们使

  • 我有以下模式- [名称:StringType,Grades:ArrayType(StructType(StructField(subject_grades),ArrayType(StructType(StructField(subject,StringType,false)),StructField(grade,LongType,false) 我想在数组中的subject字段上,该数组位于grad

  • 我想根据性别将Person对象与收集器分组。toMap()函数如下所述,但这并不像我预期的那样工作。 错误提示 不兼容类型:推理变量U具有不兼容的边界相等约束:列出下界:Person,T#2,T#1,其中U,T#1,K,T#2是类型变量:U扩展方法中声明的对象 的类型 有人能解释这个错误吗?

  • 问题是: 你有N (N代表你拥有的数字的数量)个数字。将他们分成两组,使各组数字之和的差异最小。 例子: 如果我们把1、9和3放在A组,把5和8放在B组,差异是0。 我认为首先我应该计算所有数字的总和并将其除以2。然后检查任何可能的数字组合,其总和不大于所有数字之和的一半。完成此操作后,我将选择最大的数字并打印出组。 我对所有的组合都有问题,特别是当N是大数字时。如何运行所有组合? 我的想法也有点