如果存在则将对象推入数组,否则将对象设置在MongoDB中。

7

这是我目前拥有的文档:

{
    "_id": "",
    "title": "My Watchlist",
    "series": [{
        "seriesId": 1,
        "following": true,
        "seasons": []
    }, {
        "seriesId": 1,
        "following": false,
        "seasons": []
    }]
}

您可以看到,当前有两个系列ID为1的对象,但后面的布尔值不同。

如果查询与_id匹配,则应将新对象推入系列中,如果在"series"数组中已经存在具有相同"seriesId"的对象,则应更改该对象中的字段,而不是添加新对象。

我目前有以下查询:

users.update(
    {"_id": req.body.userId},
    {
        "$push": {
            "series": {"seriesId": req.body.seriesId, "following": req.body.following}
        }
    }, (err, data) => {
        if (err)
            next(err);
    });

如果我使用$set,它不会在对象原本不存在的情况下添加对象,据我所知,你不能同时使用$push和$set。有没有办法解决这个问题,或者我必须重新考虑我的模式?

可能是 Can mongo upsert array data? 的重复问题。 - Mohammad Yusuf
1个回答

13

您可以使用两个update查询:

  • 如果找到_id并且seriesId不在数组中,则将新项添加到数组中:

db.series.update({
    "_id": req.body.userId,
    "series": {
        "$not": {
            "$elemMatch": {
                "seriesId": req.body.seriesId
            }
        }
    }
}, {
    $addToSet: {
        series: {
            "seriesId": req.body.seriesId,
            "following": req.body.following,
            "seasons": []
        }
    }
}, { multi: true });
  • 如果在数组中找到 _idseriesId,则更新该数组项:

  • db.series.update({
        "_id": req.body.userId,
        "series.seriesId": req.body.seriesId
    }, {
        $set: {
            "series.$.following": req.body.following
        }
    }, { multi: true });
    

    由于在测试和实际更新之间可能会发生一些事情,因此这是不安全的设计。为了使这种设计变得安全,您需要在这两个操作周围添加某种事务或补偿机制。 - HakonIngvaldsen

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接