как скопировать значения одного документа массива в другой документ в mongoose - PullRequest
0 голосов
/ 06 июля 2019

Я пытаюсь скопировать данные одного документа массива в другой документ массива, используя mongoose с nodejs. элементы массива документа имеют ссылку / objectId на другую коллекцию. Я использую $set для того, чтобы получить эту функцию следующим образом:

var criteria = {
     mId: {
        $in: ["id1", "id2", "id3"]
     }
};
var options = {
    multi: true
}

var dataToSet = {
    $set : {
       destinationDocument : "$sourceDocument",
    }
}
table_name.update(criteria, dataToSet, options, function(err,result){
        if(err) {
           console.log(err)
        }
    });

Но я получаю следующую ошибку:

Cast to [ObjectId] failed for value "["$sourceDocument"]" at path "destinationDocument"

моя схема БД выглядит так

new Schema({
    idAutoIncrement: { type: Number,unique: true,index:true,sparse:true},
    destinationDocument: [{
        type: Schema.Types.ObjectId,
        ref: "Users",
    }],
    sourceDocument: [{
        type: Schema.Types.ObjectId,
        ref: "Users",
    }],
});

Может кто-нибудь помочь мне разобраться, что мне нужно сделать, чтобы скопировать все значения от sourceDocument до destinationDocument. Любая помощь будет оценена. Спасибо

Ответы [ 2 ]

0 голосов
/ 06 июля 2019

Вы можете использовать конвейер агрегации с $ out для обновления той же коллекции.

Но будьте осторожны при использовании $out. Согласно официальной документации mongodb:

Создать новую коллекцию

Операция $out создает новую коллекцию в текущей базе данных, если она еще не существует. коллекция не видна, пока агрегация не завершится. Если Сбой агрегирования, MongoDB не создает коллекцию.

Заменить существующую коллекцию

Если коллекция, указанная в операции $out, уже существует, то по завершении агрегация, этап $out атомарно заменяет существующий коллекция с новой коллекцией результатов. В частности, $out операции:

  1. Создает временную коллекцию.
  2. Копирует индексы из существующих коллекция для временной коллекции.
  3. Вставляет документы в временная коллекция.
  4. Вызывает db.collection.renameCollection с dropTarget: true, чтобы переименовать временную коллекцию в место назначения коллекция.

Операция $out не изменяет индексы, которые существовали на предыдущая коллекция. В случае сбоя агрегации операция $out не вносит изменений в уже существующую коллекцию.

Попробуйте это:

table_name.aggregate([{
    $match : {
        mId: {
            $in: ["id1", "id2", "id3"]
        }
    }
},{
    $project : {
        idAutoIncrement: "$idAutoIncrement",
        destinationDocument: "$sourceDocument",
        sourceDocument: "$sourceDocument"
    }
},{
    $out : "table_name"
}])

Не забудьте перейти к этапу проекта, который вам нужен в коллекции. И, пожалуйста, сначала дважды проверьте выходное значение, либо с другой временной_коллекцией, либо просто удалив этап $ out и проверив результат конвейера агрегации.

Для получения подробной информации, пожалуйста, прочитайте Официальную документацию $ out MongoDB.

0 голосов
/ 06 июля 2019
var arrayOfDocuments = [documentId1, documentId2, documentId3];

arrayOfDocuments.foreach(function(documentId) {

    var criteria = {
        mId: documentId
    };

    // Get column2 from a document
    const documentColumnTwo = await table_name.findById(documentId).select('column2');

    // Set column1 to column2
    var dataToSet = {
        $set : {
            'column1' : documentColumnTwo,
        }
    }

    // Update the document
    await table_name.update(criteria, dataToSet, options, function(err, result) {
        if(err) {
            console.log(err)
        }
    });
})
...