在 Mongodb 中执行数据清理
Posted
技术标签:
【中文标题】在 Mongodb 中执行数据清理【英文标题】:Performing Data Cleanup In Mongodb 【发布时间】:2020-06-23 18:04:47 【问题描述】:我的应用程序跟踪整个系统中的数据移动。当记录移动时,它被放置在一个单独的集合中,以确定文档是在途中、可用还是停止服务。我使用 $addToSet 来放置 _id,并使用 $pullAll 来确保当文档从 enroute 移动到可用时,它不会重复。但是当 _id 完全移动到新位置时,我需要从旧位置删除旧数据并将其插入新位置。插入有效,但我无法弄清楚如何从旧位置正确删除数据。这些都在 Meteor Calls 和 Mongodb 中
if last.status is "Enroute"
LastLocation.update locationId: last.locationId,partId: last.partId,
$addToSet:
enroutePurchaseIds: lastPurchaseId
$pullAll:
availiblePurchaseIds: lastPurchaseId
outOfServicePurchaseIds: lastPurchaseId
【问题讨论】:
` 插入有效,但我不知道如何从旧位置正确删除数据` 这是否指的是$pullAll
操作?您能否添加一些简短的样本数据集、当前结果和预期结果?
由于您使用的是$pull
和$addToSet
,这意味着您将这些数据id 保存在数组中(在文档中)。您知道被跟踪文档的 _id
值和 _old 位置(这必须是文档中跟踪 dat 的字段)。因此,您可以查询该文档并对其进行更新($pull 是一个更新操作)。 “...但我不知道如何从旧位置正确删除数据。”你能更详细地分享这个问题吗?
【参考方案1】:
更新
您可以从即将发布的 4.4 版本中运行合并命令,该命令允许更新正在运行聚合的同一集合。将数组作为旧位置和新位置传递
db.collection.aggregate([
"$match":"location":"$in":[oldLocation,newLocation],
"$addFields":"sortOrder":"$indexOfArray":[[oldLocation,newLocation],"$location"],
"$sort":"sortOrder":1,
"$group":
"_id":null,
"oldLocationDoc":"$first":"$$ROOT",
"newLocationDoc":"$last":"$$ROOT"
,
"$addFields":
"oldLocationDoc.old":
"$filter":
"input":"$oldLocationDoc.old",
"cond":"$ne":["$$this",oldLocation]
,
"newLocationDoc.new":"$concatArrays":["$newLocationDoc.new",[newLocation]]
,
"$project":"locations":["$oldLocationDoc","$newLocationDoc"],
"$unwind":"$locations",
"$replaceRoot":"newRoot":"$locations",
"$merge":
"into":"db":"db","coll":"collection",
"on":"_id",
"whenMatched":"merge",
"whenNotMatched":"failed"
]
原创
无法在单个更新操作中将数组/字段值从一个文档移动到另一个文档。
您可能希望使用transactions
以原子方式执行多文档更新。需要副本集。
var session = db.getMongo().startSession();
var collection = session.getDatabase('test').getCollection('collection');
session.startTransaction(readConcern: level:'snapshot',writeConcern: w:'majority');
collection.update(location:oldLocation,$pull:availiblePurchaseIds:lastPurchaseId);
collection.update(location:newLocation,$push:enroutePurchaseIds:lastPurchaseId);
session.commitTransaction()
session.endSession()
其他选项是在独立的 mongod 实例的情况下执行 bulk
更新。
var bulk = db.getCollection('collection').initializeUnorderedBulkOp();
bulk.find(location:oldLocation).updateOne($pull:availiblePurchaseIds:lastPurchaseId);
bulk.find(location:newLocation).updateOne($push:enroutePurchaseIds:lastPurchaseId);
bulk.execute();
【讨论】:
【参考方案2】:您是将整个文档从一个集合移动到另一个集合还是只是移动文档的 ID?我对coffeescript 帮不上什么忙,但是如果您要移动整个文档,您可能会发现以下线程很有帮助。
mongodb move documents from one collection to another collection
【讨论】:
感谢您的文章,但不,我不会将一个文档从一个集合移动到另一个文档。我正在将 ID 从一个文档移动到另一个文档。当 id 被放入另一个文档时,我需要将它从它来自的文档中删除。以上是关于在 Mongodb 中执行数据清理的主要内容,如果未能解决你的问题,请参考以下文章