在 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 中执行数据清理的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB查看数据库集合的占用空间,清理集合的冗存空间

使用MongoDB命令工具导出导入数据

mongodb 2.6.x 清理过大日志文件的方法

mongodb的日志清理学习整理

MongoDB释放磁盘空间

MongoDB 删除文档