3

我正在 Node 中创建一个包含一些 CRUD 组件的应用程序。在我的一个数据对象上,我有一个save()方法,如果该对象具有在集合中找到的 id,则更新记录,如果没有,则更新新文档。此外,如果进行 upsert,我想取回 Mongo 生成的文档的 _id。

似乎findAndModify会这样做,而且确实,它确实从数据库中返回了一个 _id 值。在我的查询子句中,我按 _id 过滤。如果我的数据对象没有 id,Mongo 会正确执行 upsert,但是,无论它返回什么 _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);
        }
    }); 
}

我只是在寻找更新的语义,它也恰好在 upsert 上返回 Mongo 生成的 _id。我不希望query额外附加子句的值,就好像它们在update地图中一样。有什么方法可以实现我的目标吗?

4

1 回答 1

2

您可以生成 _id 客户端,使用 newnew require('mongodb').ObjectID() 然后您可以执行常规 upsert(无需查找和修改),因为您已经有了 _id。

但是,如果您使用 findAndModify,请记住节点驱动程序在位置上接受此函数的参数,而不是作为对象(如在常规 mongo shell 中)。使用节点驱动程序进行查找和修改的正确格式如下所示:

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 回答