从MongoDB中删除与数组中包含的属性值相同的文档
我正在努力从MongoDB 3.0数据库中删除共享两个属性值从MongoDB中删除与数组中包含的属性值相同的文档,mongodb,mongodb-query,Mongodb,Mongodb Query,我正在努力从MongoDB 3.0数据库中删除共享两个属性值profiles.platform和profiles.handle的文档 { _id: ID profiles: [{ source: {}, isProfile: Boolean, profile: {}, demographics: { male: Number, female: Number
profiles.platform
和profiles.handle
的文档
{
_id: ID
profiles: [{
source: {},
isProfile: Boolean,
profile: {},
demographics: {
male: Number,
female: Number
},
handle: String,
platform: String
}]
}
我尝试使用聚合框架获取共享这些属性值的文档的_id
db.collection.aggregate([{
"$group": {
"_id": "$id",
"duplicates": {
"$addToSet": "$_id"
},
"handles": {
"$addToSet": "$profiles.profile.handle",
"$addToSet": "$profiles.profile.platform"
},
"count": {
"$sum": 1
}
}
}, {
"$match": {
"count": {
"$gt": 1
}
}
}, {
"$out": "dupes"
}])
但这并不奏效。我犯了个错误
{
"errmsg": "exception: insert for $out failed: { lastOp: Timestamp 1433113685000|1, connectionId: 4856701, err: \"BSONObj size: 56348873 (0x35BD0C9) is invalid. Size must be between 0 and 16793600(16MB) First element: _id: null\", code: 10334, n: 0, ok: 1.0 }",
"code": 16996,
"ok": 0
}
重复文档的示例文件1
{
_id: ID
profiles: [{
source: {},
isProfile: true,
profile: {},
demographics: {
male: 1,
female: 0
},
handle:'tom', <--- specific property that is duplicated.
platform:'myspace' <--- specific property that is duplicated.
}]
}
{
_id:id
简介:[{
资料来源:{},
isProfile:是的,
档案:{},
人口统计:{
男:1,,
女:0
},
handle:'tom',删除恰好包含具有特定属性的数组项的文档,并将另一个文档与具有这些属性的共享数组项相匹配,这不是一个简单的操作
可能最好结合使用聚合框架和单独的批量写入操作来实现这一点
var bulk=db.collection.initializeOrderedBulkOp(),
计数=0;
db.collection.aggregate([
//展开阵列
{“$unwind”:“$profiles”},
//按所需键分组并计数
{“$组”:{
“_id”:{
“句柄”:“$profiles.handle”,
“平台”:“$profiles.platform”
},
“计数”:{“$sum”:1}
“id”:{“$addToSet”:“$\u id”}
}},
//过滤任何不重复的内容
{“$match”:{“count”:{“$gt”:1}}},
]).forEach(功能(文档){
doc.ids.shift();//删除要保留的第一项
bulk.remove({“\u id”:{“$in”:doc.ids}});
计数++;
//每1000次仅执行一次并重新初始化
如果(计数%1000==0){
bulk.execute();
bulk=db.collecion.initializeOrderedBulkOp();
}
});
//清除任何排队的
如果(计数%1000!=0)
bulk.execute();
基本上,首先“识别”包含重复项的文档,然后“保留”一个文档,或者“排除”删除其中一个文档,然后对列表中的每个“重复项”处理.remove()
您可以进一步通过额外的“重复消除”文档本身来实现这一点,但这可能是一种相当安全的方法,因为几乎没有可能的额外开销
虽然方便,但我个人不会在这里使用$out
,也不会尝试在聚合管道中完成所有工作。主要原因是将整个文档“保留”在这样的分组中可能会超出16MB BSON限制,而且尝试“标记”重复条目并仅保留一个条目也会带来大量开销
如果您有$out
,那么您的MongoDB也支持批量操作,因此最好使用它们来减少流量。尝试删除“句柄…”查询的一部分。您达到了Mongo的16MB文档限制。这不起作用。MongoDB有大约200万条记录。实际上,您正在带回每个文档。您按id进行分组,并且是唯一的。您想按profile.profile.handle和/或profile.profile.profile进行分组。您能举一个重复的d的示例吗文档?我明白了。但我一直在寻找复制的特定属性。听起来你需要$unwind你的配置文件数组并在profiles.profile.handle或profiles.profile.platform上分组。你可能需要分两步完成。我在这里看到的“不清楚”是你要求从“数组内”删除“重复项”在每个文档中或在不同的文档中,“可能”在其中一个数组项中是否具有相同的属性?那么需要删除什么?文档还是文档中的数组项?
{
_id: ID
profiles: [{
source: {},
isProfile: true,
profile: {},
demographics: {
male: 1,
female: 0
},
handle:'tom', <--- specific property that is duplicated.
platform:'myspace' <--- specific property that is duplicated.
}]
}