如何在 MongoDB/mongoose 中交换具有唯一约束的文档字段?

How to swap fields on docs with unique constraint in MongoDB/mongoose?

我有系列文档:

[{
    _id: ObjectId(),
    position: 1,
    name: 'This doc'
},
{
    _id: ObjectId(),
    position: 2
    name: 'That doc'
}]

position 字段具有唯一约束。另外,我需要它们全部有序,从 1 到 n,没有孔。

我怎样才能交换那些东西?如果我将 pos:1 设置为 pos:2 并反过来,我尝试保存,但在第一个文档中出现验证错误。或者当我试图保存整个系列时,它更难(即将文档从 pos 7 移动到 pos 2,这反过来将所有 2-6 向下移动一个)。

使用 MongoDB 执行此操作的好策略是什么?并且,最好适用于 Mongoose 模型或模式?

交换除 position.

之外的所有 other 字段
var query = {$or:[{position: 1},{position: 2}]};
Schema.find(query, function(err, docs){
    Object.keys(docs[0]).forEach(function(key){
        if(key=='position') return;
        var temp = docs[0][key];
        docs[0][key] = docs[1][key];
        docs[1][key] = temp;
    });
    docs[0].save();
    docs[1].save();
});

我 运行 遇到了类似的问题,即在数组中交换文档。我使用 Mongoose 数组 "set" 函数找到了一个很好的解决方案。这是 Mongoose 文档的 link:

http://mongoosejs.com/docs/api.html#types_array_MongooseArray.set

例如,文档保存在数据库中:

{
    "_id" : ObjectId("57a7f57258bf04b578c6ce0c"),
    "name" : "playlist_1",
    "songs" : [
        {
            "artist" : "Brand New",
            "album" : "The Devil and God",
            "title" : "Archers",
            "album_pic" : "29.mp3",
            "song" : "0.jpg",
            "_id" : ObjectId("57a7f62d58bf04b578c6ce0d")
        },
        {
            "artist" : "Modest Mouse",
            "album" : "Lonesome Crowded",
            "title" : "Cowboy Dan",
            "album_pic" : "31.mp3",
            "song" : "30.jpg",
            "_id" : ObjectId("57a7f63c58bf04b578c6ce0e")
        },
        {
            "artist" : "Portugal. The Man",
            "album" : "The Satanic Satanist",
            "title" : "People Say",
            "album_pic" : "33.mp3",
            "song" : "32.jpg",
            "_id" : ObjectId("57a7f65758bf04b578c6ce0f")
        }
    ],
    "__v" : 3
}

这是交换"songs"中数组项的函数:

function swapSongs (songIndex1, songIndex2) {
    var playlistName = 'playlist_1',
        swap1,
        swap2;

    //Model called playlist
    Playlist.findOne({name: playlistName}, function (err, playlist) {
        swap1 = playlist.songs[songIndex1];
        swap2 = playlist.songs[songIndex2];
        playlist.songs.set(songIndex1, swap2); //.set(index, newThing)
        playlist.songs.set(songIndex2, swap1);
        playlist.save();
    });
}

这是swapSongs(0,2);

的结果
{
    "_id" : ObjectId("57a7f57258bf04b578c6ce0c"),
    "name" : "playlist_1",
    "songs" : [
        {
            "artist" : "Portugal. The Man",
            "album" : "The Satanic Satanist",
            "title" : "People Say",
            "album_pic" : "33.mp3",
            "song" : "32.jpg",
            "_id" : ObjectId("57a7f65758bf04b578c6ce0f")
        },
        {
            "artist" : "Modest Mouse",
            "album" : "Lonesome Crowded",
            "title" : "Cowboy Dan",
            "album_pic" : "31.mp3",
            "song" : "30.jpg",
            "_id" : ObjectId("57a7f63c58bf04b578c6ce0e")
        },
        {
            "artist" : "Brand New",
            "album" : "The Devil and God",
            "title" : "Archers",
            "album_pic" : "29.mp3",
            "song" : "0.jpg",
            "_id" : ObjectId("57a7f62d58bf04b578c6ce0d")
        }
    ],
    "__v" : 3
}

希望对您有所帮助!