我有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)。由于doc(1& 2)和doc(1& 3)之间有一个共同的电子邮件ID,因此这3个代表一个联系人,应该作为一个联系人合并为一个。
我尝试使用$ unwind和java中的$ 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用于所有可能的重复联系人(可能有另一组带有_ids列表的重复项),以便我可以提示用户和用户可以按照他的意愿合并它们。 希望现在更清楚。谢谢!
答案 0 :(得分:0)
那么你的问题与你所寻求的结果略有不同。您的初始问题向我指出了以下聚合:
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")
]
}