Chatrooms.findOneAndUpdate({Roomname: room.Roomname},{ $setOnInsert: {status: true, userNum: 1}}, {new: true, upsert: true}, function(err, doc) {
if(err) console.log(err);
console.log("DOC " + doc)
if(doc.status) {
// FOUND ROOM SATTUS IS TRUE LOGIC
console.log(doc);
// return callback(true)
}
});
上面的查询将返回给我更新或插入的实际文档,但我无法准确检查它是哪一个。如果我进行更新而不是 findOneandUpdate 我会返回此
{
ok: 1,
nModified: 0,
n: 1,
upserted: [ { index: 0, _id: 55df883dd5c3f7cda6f84c78 } ]
}
如何返回文档和写入结果,或者至少返回写入结果中插入的字段。
自 2019 年 8 月 8 日起(Mongoose 版本 5.6.9),要设置的属性是“rawResult”而不是“passRawResult”:
M.findOneAndUpdate({}, obj, {new: true, upsert: true, rawResult:true}, function(err, d) {
if(err) console.log(err);
console.log(d);
});
输出:
{ lastErrorObject:
{ n: 1,
updatedExisting: false,
upserted: 5d4befa6b44b48c3f2d21c75 },
value: { _id: 5d4befa6b44b48c3f2d21c75, rating: 4, review: 'QQQ' },
ok: 1 }
还要注意,结果作为回调的第二个参数返回,而不是第三个参数。可以通过d.value检索文档。
Mongoose 4.1.10 版本有一个名为
passRawResult
的选项,如果设置为 true
会导致传递 raw
参数。忽略此选项似乎默认为 false
并导致 raw
始终为 undefined
:
passRawResult:如果为 true,则传递来自 MongoDB 驱动程序的原始结果 作为第三个回调参数
http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate
好吧,我的主要问题是我无法获取插入文档的_id,而无法检查它是否已更新/找到或插入。不过我了解到您可以生成自己的 ID。
id = mongoose.Types.ObjectId();
Chatrooms.findOneAndUpdate({Roomname: room.Roomname},{ $setOnInsert: {_id: id, status: true, userNum: 1}}, {new: true, upsert: true}, function(err, doc) {
if(err) console.log(err);
if(doc === null) {
// inserted document logic
// _id available for inserted document via id
} else if(doc.status) {
// found document logic
}
});
更新
猫鼬API v4.4.8
passRawResult:如果为 true,则将 MongoDB 驱动程序的原始结果作为第三个回调参数传递。
我担心使用 FindOneAndUpdate 不能做你想做的事,因为它没有中间件和设置器,并且它在文档中提到了它:
虽然在使用 findAndModify 帮助器时将值转换为适当的类型,但不应用以下内容:
http://mongoosejs.com/docs/api.html在findOneAndUpdate中搜索它
如果您想获取更新前的文档和更新后的文档,您可以这样做:
Model.findOne({ name: 'borne' }, function (err, doc) {
if (doc){
console.log(doc);//this is ur document before update
doc.name = 'jason borne';
doc.save(callback); // you can use your own callback to get the udpated doc
}
})
希望对你有帮助
我不知道这是如何完全偏离轨道的,但对于所有
.XXupdate()
方法始终有“第三个”参数响应,这基本上是来自驱动程序的原始响应。这总是告诉您文档是否被“更新插入”:
Chatrooms.findOneAndUpdate(
{ "Roomname": room.Roomname },
{ "$setOnInsert": {
"status": true, "userNum": 1
}},
{ "new": true, "upsert": true },
function(err, doc,raw) {
if(err) console.log(err);
// Check if upserted
if ( raw.lasErrorObject.n == 1 && !raw.lastErrorObject.updatedExisting ) {
console.log("upserted: %s", raw.lastErrorObject.upserted);
}
console.log("DOC " + doc)
if (doc.status) {
// FOUND ROOM SATTUS IS TRUE LOGIC
console.log(doc);
// return callback(true)
}
});
这会告诉您刚刚更新插入的文档的
_id
。
来自“原始”响应中的类似内容:
{ lastErrorObject:
{ updatedExisting: false,
n: 1,
upserted: 55e12c65f6044f57c8e09a46 },
value: { _id: 55e12c65f6044f57c8e09a46,
status: true,
userNum: 1
__v: 0 },
ok: 1 }
完整的可复制列表:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
var testSchema = new Schema({
name: String
});
var Test = mongoose.model('Test', testSchema, 'test');
async.series(
[
function(callback) {
Test.remove({},callback);
},
function(callback) {
async.eachSeries(
["first","second"],
function(it,callback) {
console.log(it);
Test.findOneAndUpdate(
{ "name": "Bill" },
{ "$set": { "name": "Bill" } },
{ "new": true, "upsert": true },
function(err,doc,raw) {
console.log(raw),
console.log(doc),
callback(err);
}
);
},
callback
);
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
哪个输出:
first
{ lastErrorObject:
{ updatedExisting: false,
n: 1,
upserted: 55e2a92328f7d03a06a2dd6b },
value: { _id: 55e2a92328f7d03a06a2dd6b, name: 'Bill', __v: 0 },
ok: 1 }
{ _id: 55e2a92328f7d03a06a2dd6b, name: 'Bill', __v: 0 }
second
{ lastErrorObject: { updatedExisting: true, n: 1 },
value: { _id: 55e2a92328f7d03a06a2dd6b, name: 'Bill', __v: 0 },
ok: 1 }
{ _id: 55e2a92328f7d03a06a2dd6b, name: 'Bill', __v: 0 }
在 mongoose 8.1.3 中,要设置的属性是“includeResultMetadata”,而不是“rawResult”或“passRawResult”。