【问题标题】:mongodb: atomically remove first n elements of arraymongodb:原子地删除数组的前n个元素
【发布时间】:2023-04-01 22:17:01
【问题描述】:

我想自动删除数组字段的前 n 个元素。

现在,我使用model.find(),然后是doc.arrayField.slice(n),然后是doc.save()。但这会将整个文档加载到内存中(如果文档非常大,则不好),并且会破坏原子性。

有没有办法在 MongoDB/Mongoose 中以原子方式实现这一点?

谢谢!

【问题讨论】:

    标签: javascript arrays node.js mongodb mongoose


    【解决方案1】:

    您可以使用$pop 以原子方式删除第一个元素。或者,如果您可以指定要删除的字段,您可以使用$pull 从数组中删除多个项目。否则,您无法使用 mongodb 在原子操作中从数组中删除前 n 个元素。

    db.yourCollection.update({}, {$pop: {arrayField: 1}}}) // will remove the first element from arrayField
    
    db.yourCollection.update({}, {$pull: {arrayField: {foo: "bar"}}}}) // will remove all elements whose foo field equal to bar from arrayField.
    

    【讨论】:

    • 要删除前n个元素,slice可以用来保存前n个元素。所以在你的情况下,我认为它不会帮助你。但是,如果您知道数组的大小,您可能会再次使用 slice 运算符和 each 运算符来保留最后 n 个元素。例如 db.yourCollection.update({}, {$pull: {arrayField: {$each:[], $slice: -5}}}}) // 将保留数组的最后 5 个元素
    • 删除第一个元素应该使用 -1 而不是 1。
    【解决方案2】:

    MongoDB 为数组更新提供$slice 运算符。 https://docs.mongodb.org/v3.0/reference/operator/update/slice/

    你也可以在 Mongoose updateClause 中使用。

    【讨论】:

      【解决方案3】:

      您可以使用$sliceproject文档,而不是将所有arrayField 数据加载到内存中,像这样

      model.find({}, {arrayField : {$slice: n}}) // n is first n elements
      

      现在您可以使用

      删除这 n 个元素
      doc.arrayField.slice(n);
      doc.save();
      

      【讨论】:

      • 这是两个操作。所以它不是原子的。
      猜你喜欢
      • 2012-04-01
      • 1970-01-01
      • 2020-07-17
      • 1970-01-01
      • 1970-01-01
      • 2021-06-26
      • 2023-03-27
      • 1970-01-01
      • 2011-11-13
      相关资源
      最近更新 更多