在Mongoose中升级子文档

时间:2016-11-29 16:31:28

标签: node.js mongodb mongoose

我试图将连续的子文档添加到文档中。目标是每个子文档只在数组中出现一次。如果它存在,它应该更新。我认为这被称为" upsert"。

示例架构

var playlistSchema = mongoose.Schema({
    name: String,
    tracks:[
        {
            name: String,
            artist: String
        }]
});

查询

var query = {'name': 'Playlist1'},
    update1 = {'$push': { 'tracks': {'name' : 'First Track', 'artist': 'artist'}}},
    update2 = {'$push': { 'tracks': {'name' : 'First Track', 'artist': 'new artist'}}},
    update3 = {'$push': { 'tracks': {'name' : 'Second Track', 'artist': 'artist'}}},
    options = {upsert: true};

playlistSchema.findOneAndUpdate(query, update1, options, function (err, playlist) {});
playlistSchema.findOneAndUpdate(query, update2, options, function (err, playlist) {});
playlistSchema.findOneAndUpdate(query, update3, options, function (err, playlist) {});

我得到了什么

"name": "Playlist1", 
"tracks": [{"name": "First Track", "artist": "artist"},
           {"name": "First Track", "artist": "new artist"},
           {"name": "Second Track", "artist": "artist"}]

我的目标

"name": "Playlist1" ,   
"tracks": [{"name": "First Track", "artist": "new artist"},
           {"name": "Second Track", "artist": "artist"}]

我可能需要查询一个特定的子文档,但我不知道如何。

2 个答案:

答案 0 :(得分:1)

$ addToSet 替换 $ push 后,它按预期工作。

var query = {'name': 'Playlist1'},
    update1 = {'$addToSet': { 'tracks': {'name' : 'First Track', 'artist': 'artist'}}},
    options = {};

playlistSchema.findOneAndUpdate(query, update1, options, function (err, playlist) {});

答案 1 :(得分:0)

如果您知道已添加曲目,则可以使用位置更新来更新阵列中的元素。

Reference

例如:

db.playlists.update(
    {'name': 'Playlist1', 'tracks.name': 'First Track'}, 
    {'$set': { 'tracks.$.artist': 'new artist'}}
);

这将找到播放列表1'并且能够确定它在轨道阵列中的哪个位置匹配' First Track'并将其存储在' $'运营商。然后,当您更新$ set中的艺术家时,它将使用新的变量覆盖该变量。

这可能不是您正在寻找的确切解决方案,但希望它能为您指明正确的方向。