【问题标题】:How to prepend an array and remove dupes in Mongo?如何在 Mongo 中添加一个数组并删除欺骗?
【发布时间】:2014-07-03 21:01:20
【问题描述】:

在 MongoDB 中,将一个项目添加到数组中并删除任何重复项目的好方法是什么?

如果项目已经在数组中,$addToSet 不会做任何事情。

SO question 显示了两种前置方式,但不会删除欺骗。

使用 Mongo 2.4.1、MongoMapper 和 Ruby。

【问题讨论】:

    标签: ruby mongodb mongodb-query mongomapper


    【解决方案1】:

    您可以通过限定您的update 条件来包含要添加的值不在数组中来做到这一点。然后通过将$push$each$position 一起使用,您可以将项目插入到数组的开头,前提是它尚未出现在数组中。

    假设一个文档看起来像:

    {
      "_id": 1,
      "a": [1]
    }
    

    您可以在 shell 中执行更新:

    var value = 1;
    db.test.update(
        {_id: 1, a: {$ne: value}}, 
        {$push: {a: {$each: [value], $position: 0}}})
    

    对于 1 的 value 无效,但任何其他值都将添加到 a 数组字段之前。

    【讨论】:

    • 谢谢。这很有帮助。实际上,它应该始终预先设置并删除任何欺骗。也就是说,如果元素已经存在,那么它应该被移到数组的前面。
    • 好的,我不太清楚你删除欺骗是什么意思,因为这似乎与在数组开头插入是一个单独的问题。
    【解决方案2】:

    $addToSet 运算符当然不会删除现有的重复项,而且作为“集合”的任何元素都不会被认为是有序的,因此无法使用此运算符定位它们。

    在任何一种情况下,按照您的逻辑来处理重复项现在都由您来管理。但是,bulk operations API 可以为您提供帮助,而不是拉取文档并在代码中进行操作,这可能会导致并发问题。

    因此,为了确保您的逻辑,您将使用 $pull 从您插入的数组中删除任何项目,然后使用 $push,使用需要与 @987654326 耦合的 $position 修饰符@修饰符。

    一个基本的mongomapper代码示例:

    require 'mongo_mapper'
    require 'pp'
    
    MongoMapper.database = 'test'
    
    class User
      include MongoMapper::Document
    
      key :array, Array
    end
    User.collection.remove
    
    user = User.create(:array => [5, 4, 4, 6])
    
    pp user
    
    bulk = User.collection.initialize_unordered_bulk_op
    
    bulk.find(:_id => user._id, :array => 4)
      .update_one({ "$pull" => { "array" => 4 }})
    
    bulk.find({"_id" => user._id, "array" => { "$ne" => 4 }})
      .update_one({
        "$push" => {
          "array" => { "$each" => [4], "$position" => 0 }
        }
      })
    
    res = bulk.execute()
    
    pp res
    
    pp user.reload
    

    严格来说,这仍然不是原子操作,而是在多次更新中执行的。但是 API 实现确实通过网络将这两个请求一起发送并连续实现它们。因此,这与您当前将要获得的逻辑一样接近原子操作。

    这个例子中的结果数组当然是:

    array: [4, 5, 6]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-07
      • 2010-11-11
      • 1970-01-01
      • 1970-01-01
      • 2011-03-07
      • 2011-09-04
      • 1970-01-01
      相关资源
      最近更新 更多