3

いくつかのCRUDコンポーネントを持つNodeでアプリケーションを作成しています。私のデータオブジェクトの1つに、オブジェクトにsave()コレクションで見つかったIDがある場合はレコードを更新し、そうでない場合は新しいドキュメントをアップサートすることを目的としたメソッドがあります。さらに、アップサートを行う場合は、Mongoによって生成されたドキュメントの_idを取得したいと思います。

findAndModifyがこれを行うようであり、実際、データベースから_id値を返します。クエリ句では、_idでフィルタリングしています。データオブジェクトにIDがない場合、Mongoは正しくアップサートを実行しますが、返される_id値に関係なく、update句で設定しているキーに加えて、に基づいてドキュメントに_idも設定します。query句で使用した値。明確にするためのいくつかのコード:

User.prototype.save = function(callback) {
    var that = this;

    var args = {
        'query'     : { _id: this.getId() }, //getId() returns empty string if not set
        'update'    : { $set : {
            firstName   : this.firstName,
            lastName    : this.lastName,
            email       : this.email
          //_id        : this.getId()
          // which is blank, is magically getting added due to query clause
        }},
        'new'       : true,
        'upsert'    : true,
        'fields'    : {'_id' : true}
    };

    this.db.collection(dbName).findAndModify(args, function(err, doc){
        if(!that.getId()) {
            that.setId(doc._id);
        }

        if (typeof(callback) === "function"){
            callback.call(that);
        }
    }); 
}

私は単に、更新のセマンティクスを探しています。これは、アップサートでMongoによって生成された_idを返すこともあります。句の値を、マップquery内にあるかのように追加したくありません。update私が得ていることを達成する方法はありますか?

4

1 に答える 1

2

newを使用して_idクライアント側を生成できますnew require('mongodb').ObjectID() 。その後、すでに_idがあるため、通常のアップサートを実行できます(findandmodifyを実行する必要はありません)。

ただし、findAndModifyを使用している場合は、ノードドライバーが、オブジェクトとしてではなく(通常のmongoシェルのように)、この関数への引数を位置的に受け入れることに注意してください。ノードドライバを使用してfindandmodifyを実行するための正しい形式は、次のようになります。

collection.findAndModify(criteria, sort, update[, options, callback])

(オプションとコールバックはオプションのパラメーターです)。完全なドキュメントはこちら: https ://github.com/mongodb/node-mongodb-native/blob/master/docs/insert.md

于 2012-04-19T15:28:17.683 に答える