从 mongo 数据库中删除除一个副本之外的所有副本
Delete all but one duplicate from a mongo db
所以我犯了一个错误,两次保存了很多文档,因为我弄乱了我的文档 ID。因为我做了一个插入,所以我每次保存文件时都会成倍增加。所以我想删除我写的第一个以外的所有重复项。幸运的是,这些文件有一个隐含的唯一键(match._id
),我应该能够分辨出第一个是什么,因为我使用的是对象 ID。
文件看起来像这样:
{
_id: "5e8e2d28ca6e660006f263e6"
match : {
_id: 2345
...
}
...
}
所以,现在我有一个聚合,告诉我哪些元素是重复的并将它们存储在一个集合中。肯定有更优雅的方法,但我还在学习。
[{$sort: {"$_id": 1},
{$group: {
_id: "$match._id",
duplicateIds: {$push: "$_id"},
count: {$sum: 1}
}},
{$match: {
count: { $gt: 1 }
}}, {$addFields: {
deletableIds: { $slice: ["$duplicateIds", 1, 1000 ] }
}},
{$out: 'DeleteableIds'}]
现在我不知道如何进一步进行,因为它似乎没有聚合中的 "delete" 操作,我不想将这些临时数据写入数据库,这样我就可以写一个删除命令,因为我想一次性删除它们。还有其他方法吗?我仍在学习 mongodb,感觉有点不知所措:/
无需执行所有这些操作,您只需为每个 _id: "$match._id"
选择 group
中的第一个文档并将其作为根文档。另外,我认为您不需要对您的情况进行排序:
db.collection.aggregate([
{
$group: {
_id: "$match._id",
doc: {
$first: "$$ROOT"
}
}
},
{
$replaceRoot: {
newRoot: "$doc"
}
}, {$out: 'DeleteableIds'}
])
我认为您的方向是正确的,但是,要删除您发现的重复项,您可以对集合使用 bulk write。
因此,如果我们假设您的聚合查询将以下内容保存在 DeleteableIds
集合
> db.DeleteableIds.insertMany([
... {deletableIds: [1,2,3,4]},
... {deletableIds: [103,35,12]},
... {deletableIds: [345,311,232,500]}
... ]);
我们现在可以使用它们并编写批量写入命令:
const bulkwrite = db.DeleteableIds.find().map(x => ({ deleteMany : { filter: { _id: { $in: x.deletableIds } } } }))
然后我们可以对数据库执行。
> db.collection1.bulkWrite(bulkwrite)
这将删除所有重复项。
所以我犯了一个错误,两次保存了很多文档,因为我弄乱了我的文档 ID。因为我做了一个插入,所以我每次保存文件时都会成倍增加。所以我想删除我写的第一个以外的所有重复项。幸运的是,这些文件有一个隐含的唯一键(match._id
),我应该能够分辨出第一个是什么,因为我使用的是对象 ID。
文件看起来像这样:
{
_id: "5e8e2d28ca6e660006f263e6"
match : {
_id: 2345
...
}
...
}
所以,现在我有一个聚合,告诉我哪些元素是重复的并将它们存储在一个集合中。肯定有更优雅的方法,但我还在学习。
[{$sort: {"$_id": 1},
{$group: {
_id: "$match._id",
duplicateIds: {$push: "$_id"},
count: {$sum: 1}
}},
{$match: {
count: { $gt: 1 }
}}, {$addFields: {
deletableIds: { $slice: ["$duplicateIds", 1, 1000 ] }
}},
{$out: 'DeleteableIds'}]
现在我不知道如何进一步进行,因为它似乎没有聚合中的 "delete" 操作,我不想将这些临时数据写入数据库,这样我就可以写一个删除命令,因为我想一次性删除它们。还有其他方法吗?我仍在学习 mongodb,感觉有点不知所措:/
无需执行所有这些操作,您只需为每个 _id: "$match._id"
选择 group
中的第一个文档并将其作为根文档。另外,我认为您不需要对您的情况进行排序:
db.collection.aggregate([
{
$group: {
_id: "$match._id",
doc: {
$first: "$$ROOT"
}
}
},
{
$replaceRoot: {
newRoot: "$doc"
}
}, {$out: 'DeleteableIds'}
])
我认为您的方向是正确的,但是,要删除您发现的重复项,您可以对集合使用 bulk write。
因此,如果我们假设您的聚合查询将以下内容保存在 DeleteableIds
集合
> db.DeleteableIds.insertMany([
... {deletableIds: [1,2,3,4]},
... {deletableIds: [103,35,12]},
... {deletableIds: [345,311,232,500]}
... ]);
我们现在可以使用它们并编写批量写入命令:
const bulkwrite = db.DeleteableIds.find().map(x => ({ deleteMany : { filter: { _id: { $in: x.deletableIds } } } }))
然后我们可以对数据库执行。
> db.collection1.bulkWrite(bulkwrite)
这将删除所有重复项。