代码之家  ›  专栏  ›  技术社区  ›  user1063287

如果对象不存在,则将对象添加到对象数组中,否则更新对象

  •  0
  • user1063287  · 技术社区  · 6 年前

    期望的行为

    如果对象不存在,则将其添加到对象数组中,否则更新对象。

    架构

    "ratings" : [ 
        {
            "user_email" : "john@smith.com",
            "criteria_a" : 0,
            "criteria_b" : 3,
            "criteria_c" : 1,
            "criteria_d" : 5,
            "criteria_e" : 2
        },
        {
            "user_email" : "bob@smith.com",
            "criteria_a" : 1,
            "criteria_b" : 3,
            "criteria_c" : 5,
            "criteria_d" : 2,
            "criteria_e" : 1
        },
        {
            "user_email" : "jane@smith.com",
            "criteria_a" : 5,
            "criteria_b" : 3,
            "criteria_c" : 1,
            "criteria_d" : 0,
            "criteria_e" : 1
        }
    ]
    

    我读过:

    这个 $addToSet 已经存在了,在这种情况下 $添加到设置 对数组没有任何影响。

    资料来源: https://docs.mongodb.com/manual/reference/operator/update/addToSet/

    但我有点困惑,因为我想我在尝试:

    • 如果对象不存在
    • $set (即更新现有对象)如果它确实存在

    以下内容不断增加 rating 对象,即使用户已经添加了分级。

    var collection = mongo_client.db("houses").collection("houses");
    
    var o_id = new ObjectID(id);
    
    var query = { _id: o_id, "ratings.user_email": user_email };
    
    var update = { $addToSet: { ratings: rating } };
    
    var options = { upsert: true };
    
    collection.updateOne(query, update, options, function(err, doc) {
        if (err) {
            res.send(err);
        } else {
            res.json({ doc: doc })
        }
    });
    

    编辑:

    The positional operator did not find the match needed from the query. :

    var update = { $set: { "ratings.$": rating } };
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   user1063287    6 年前

    1. 尝试 $push 如果给定用户还没有评级,即否定 user_email 在更新查询的匹配部分。
    2. 在上再次执行第二次更新 "ratings.user_email": user_email $set "ratings.$": rating .

    结果应该是这样的:

    collection.updateOne(
        { _id: o_id, ratings: { $not: { $elemMatch: { user_email: user_email } } } },
        { $push: { ratings: rating } }
    );
    
    collection.updateOne(
        { _id: o_id, "ratings.user_email": user_email },
        { $set: { "ratings.$": rating } }
    );
    

    // BEGIN new rating query/update variables
    var query_new_rating = { _id: o_id, ratings: { $not: { $elemMatch: { user_email: user_email } } } };
    
    var update_new_rating = { $push: { ratings: rating } };
    // END new rating  query/update variables
    
    
    //  part 01 - attempt to push a new rating
    collection.updateOne(query_new_rating, update_new_rating, function(error, result) {
    
        if (error) {
            res.send(error);
        } else {
    
            // get the number of modified documents
            // if 0 - the rating already exists
            // if 1 - a new rating was added
            var number_modified = result.result.nModified;
    
            // BEGIN if updating an existing rating
            if (number_modified === 0) {
    
                console.log("updating existing rating");
    
                // BEGIN existing rating query/update variables
                var query_existing_rating = { _id: o_id, "ratings.user_email": user_email };
    
                var update_existing_rating = { $set: { "ratings.$": rating } };
                // END existing rating query/update variables
    
                //  part 02 - update an existing rating
                collection.updateOne(query_existing_rating, update_existing_rating, function(error, result) {
    
                    if (error) {
                        res.send(error);
                    } else {
    
                        console.log("updated existing rating");
                        res.json({ result: result.result })
                    }
    
                });
    
            }
            // END if updating an existing rating
    
            // BEGIN if adding a new rating
            else if (number_modified === 1) {
    
                console.log("added new rating");
                res.json({ result: result.result })
    
            }
            // END if adding a new rating
    
        }
    });