我在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
映射中一样。有没有办法实现我的目标?
答案 0 :(得分:2)
您可以使用新的new require('mongodb').ObjectID()
生成_id客户端
然后你可以做一个常规的upsert(不需要做findandmodify),因为你已经有了_id。
但是,如果您使用的是findAndModify,请记住,节点驱动程序在位置上接受此函数的参数,而不是作为对象(如常规mongo shell中)。 使用节点驱动程序进行findandmodify的正确格式如下所示:
collection.findAndModify(criteria, sort, update[, options, callback])
(选项和回调是可选参数)。完整的文档在这里: https://github.com/mongodb/node-mongodb-native/blob/master/docs/insert.md