MongoDB - Update or Insert object in array

后端 未结 7 1952
醉话见心
醉话见心 2020-12-08 04:26

I have the following collection

{
    "_id" : ObjectId("57315ba4846dd82425ca2408"),
    "myarray" : [ 
        {
            use         


        
相关标签:
7条回答
  • 2020-12-08 05:05

    In MongoDB 3.6 it is now possible to upsert elements in an array.

    0 讨论(0)
  • 2020-12-08 05:06

    When you want update or insert value in array try it

    Object in db

    key:name,
    key1:name1,
    arr:[
        {
            val:1,
            val2:1
        }
    ]
    

    Query

    var query = {
        $inc:{
            "arr.0.val": 2,
            "arr.0.val2": 2
        }
    }
    .updateOne( { "key": name }, query, { upsert: true }
    
    key:name,
    key1:name1,
    arr:[
        {
            val:3,
            val2:3
        }
    ]
    
    0 讨论(0)
  • 2020-12-08 05:12

    Try this

    db.collection.update(
        { _id : ObjectId("57315ba4846dd82425ca2408")},
        { $pull: {"myarray.userId": ObjectId("570ca5e48dbe673802c2d035")}}
    )
    db.collection.update(
        { _id : ObjectId("57315ba4846dd82425ca2408")},
        { $push: {"myarray": {
            userId:ObjectId("570ca5e48dbe673802c2d035"),
            point: 10
        }}
    )
    

    Explination: in the first statment $pull removes the element with userId= ObjectId("570ca5e48dbe673802c2d035") from the array on the document where _id = ObjectId("57315ba4846dd82425ca2408")

    In the second one $push inserts this object { userId:ObjectId("570ca5e48dbe673802c2d035"), point: 10 } in the same array.

    0 讨论(0)
  • 2020-12-08 05:17

    array update and create don't mix in under one query, if you care much about atomicity then there's this solution:

    normalise your schema to,

    {
        "_id" : ObjectId("57315ba4846dd82425ca2408"),
        userId : ObjectId("570ca5e48dbe673802c2d035"),
        point : 5
    }
    
    0 讨论(0)
  • 2020-12-08 05:18

    The accepted answer by Flying Fisher is that the existing record will first be deleted, and then it will be pushed again.

    A safer approach (common sense) would be to try to update the record first, and if that did not find a match, insert it, like so:

    // first try to overwrite existing value
    var result = db.collection.update(
       {
           _id : ObjectId("57315ba4846dd82425ca2408"),
           "myarray.userId": ObjectId("570ca5e48dbe673802c2d035")
       },
       {
           $set: {"myarray.$.point": {point: 10}}
       }
    );
    // you probably need to modify the following if-statement to some async callback
    // checking depending on your server-side code and mongodb-driver
    if(!result.nMatched)
    {
        // record not found, so create a new entry
        // this can be done using $addToSet:
        db.collection.update(
            {
                _id: ObjectId("57315ba4846dd82425ca2408")
            },
            {
                $addToSet: {
                    myarray: {
                        userId: ObjectId("570ca5e48dbe673802c2d035"),
                        point: 10
                    }
                }
            }
        );
        // OR (the equivalent) using $push:
        db.collection.update(
            {
                _id: ObjectId("57315ba4846dd82425ca2408"),
                "myarray.userId": {$ne: ObjectId("570ca5e48dbe673802c2d035"}}
            },
            {
                $push: {
                    myarray: {
                        userId: ObjectId("570ca5e48dbe673802c2d035"),
                        point: 10
                    }
                }
            }
        );
    }
    

    This should also give (common sense, untested) an increase in performance, if in most cases the record already exists, only the first query will be executed.

    0 讨论(0)
  • Unfortunately "upsert" operation is not possible on embedded array. Operators simply do not exist so that this is not possible in a single statement.Hence you must perform two update operations in order to do what you want. Also the order of application for these two updates is important to get desired result.

    0 讨论(0)
提交回复
热议问题