我的用户集合包含许多子文档列表。架构是这样的:
{
_id: ObjectId(),
name: aaa,
age: 20,
transactions:[
{
trans_id: 1,
product: mobile,
price: 30,
},
{
trans_id: 2,
product: tv,
price: 10
},
...]
...
}
所以我有一个疑问。 trans_id
列表中的transactions
对于所有产品都是唯一的,但我可能会使用相同的trans_id
再次复制相同的事务(由于错误的ETL编程)。现在我想删除那些重复的子文档。我已经将trans_id编入索引而不是unique
。我读到了dropDups
选项。但是它会删除DB中存在的特定副本,还是会丢弃整个文档(我绝对不想要)。如果没有怎么办?
PS:我使用的是MongoDB 2.6.6版本。
答案 0 :(得分:2)
我们在这里看到的所有人都知道最近的情况,现在你需要一种方法来定义数组中的“不同”项目,其中某些项目实际上是数组中其他项目的“精确副本”。
最好的情况是在集合的循环操作中使用$addToSet
和$each
修饰符。理想情况下,您可以使用Bulk Operations API来减少流量,这样做:
var bulk = db.collection.initializeOrderedBulkOperation();
var count = 0;
// Read the docs
db.collection.find({}).forEach(function(doc) {
// Blank the array
bulk.find({ "_id": doc.id })
.updateOne({ "$set": { "transactions": [] } });
// Resend as a "set"
bulk.find({ "_id": doc.id })
.updateOne({
"$addToSet": {
"trasactions": { "$each": doc.transactions }
}
});
count++;
// Execute once every 500 statements ( actually 1000 )
if ( count % 500 == 0 ) {
bulk.execute()
bulk = db.collection.initializeOrderedBulkOperation();
}
});
// If a remainder then execute the remaining stack
if ( count % 500 != 0 )
bulk.execute();
因此,只要“重复”内容“完全相同”,那么这种方法就可以了。如果唯一实际上是“重复”的是“trans_id”字段,那么你需要一种完全不同的方法,因为“整个文档”都没有“重复”,这意味着你需要更多的逻辑来实现这一点。 / p>