web-dev-qa-db-ja.com

Mongooseで更新されたコレクションを返す

Nodejs/express/mongoose/angularjsを使用しています。 Listsという名前のコレクションを更新します。このコレクションにはいくつかのプロパティがあり、そのうちの1つはアイテムの配列です。次のコードでは、items配列に新しいタスクアイテムをプッシュしています。すべて正常に機能しますが、更新機能は更新されたコレクションを返送しないため、データベースで別のクエリを実行する必要があります。これを行うより効率的な方法はありますか?

nodejs/expressコード:

exports.addTaskToList = function(req, res) {
    var listId = req.params.Id;
    var taskId = req.params.TaskId;
    Lists.update({_id: listId}, {$Push: {items: taskId}}, {safe:true, upsert: true}, function(err, result){
        if(err) {
            console.log('Error updating todo list. ' + err);
        }
        else{
            console.log(result + ' todo list entry updated - New task added');
            Lists.findById(listId).populate('items').exec(function (err, updatedEntry) {
                if (err) {
                    console.log('Unable to retrieve todo list entry.');
                }
                res.send(JSON.stringify(updatedEntry));
            });
        }           
    });
};

さらに、配列項目はObjectIdの配列です。これらのアイテムは別個のスキーマにあるため、別個のコレクションにあります。別のコレクションが作成されないように、_idだけでなくオブジェクト全体をプッシュすることは可能ですか?

26
GuillaumeA

更新方法は更新されたドキュメントを返しません

ただし、アプリケーションでドキュメントを返す必要がなく、データベースのプロパティを直接更新するだけの場合は、Model#updateが適切です。

ドキュメントを更新して返す必要がある場合は、次のオプションのいずれかを検討してください。

従来のアプローチ:

Lists.findById(listId, function(err, list) {
    if (err) {
        ...
    } else {
        list.items.Push(taskId)
        list.save(function(err, list) {
            ...
        });
    }
});

短いアプローチ:

Lists.findByIdAndUpdate(listId, {$Push: {items: taskId}}, function(err, list) {
    ...
});
26

findOneAndUpdate()メソッドを使用し、クエリパラメーターで{"new":true}としてオプションを使用します

return this.sessionModel
       .findOneAndUpdate({user_id: data.user_id}, {$set:{session_id: suuid}}, { "new": true})
       .exec()
       .then(data=>{
        return {
          sid: data.session_id
            }
        })
20
KARTHIKEYAN.A

最後の質問について:

別のコレクションが作成されないように、_idだけでなくオブジェクト全体をプッシュすることは可能ですか?

答えはイエスです。 Mongooseを使用すると、サブドキュメントをドキュメント内に非常に簡単に保存できます( ここでサブドキュメントのドキュメント )。スキーマを少し変更するだけで、アイテムオブジェクト全体(アイテム_id)リストスキーマで定義されたアイテムの配列へ。ただし、次のようにスキーマを変更する必要があります。

var itemSchema = new Schema({ 
    // Your Item schema goes here
    task: 'string'       // For example
});

var listSchema = new Schema({
    // Your list schema goes here
    listName: String,    // For example...
    items: [itemSchema]  // Finally include an array of items
});

itemオブジェクトをリストのitemsプロパティに追加し、そのリストを保存することにより、新しいアイテムはListコレクションに保持されます。例えば、

var list = new List({
    listName: "Things to do"
});

list.items.Push({
    task: "Mow the lawn"
});

list.save(function(error, result) {
    if (error) // Handle error
    console.log(result.list) // Will contain your item instance
});

したがって、リストをロードすると、itemsプロパティにアイテムの配列が事前に入力されます。

これは、アイテムが個別のコレクションとして永続化されなくなるためです。リストのサブドキュメントとしてリストコレクションに保持されます。

1
C Blanchard