我会在这方面称其为“错误”。 Mongoose 显然做错了事,这可以在稍后显示的日志记录中得到证明。但这里有一个清单,它从本机驱动程序调用 .findOneAndUpdate(),并具有您尝试执行的相同更新:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/school');
mongoose.set('debug',true);
var userSchema = new Schema({
name: {
type: String,
required: true
},
lectures: { type: Schema.Types.Mixed }
});
var User = mongoose.model( "User", userSchema );
function logger(data) {
return JSON.stringify(data, undefined, 2);
}
async.waterfall(
[
function(callback) {
User.remove({},function(err) {
callback(err);
});
},
function(callback) {
console.log("here");
var user = new User({ "name": "bob" });
user.save(function(err,user) {
callback(err,user);
});
},
function(user,callback) {
console.log("Saved: %s", logger(user));
User.collection.findOneAndUpdate(
{ "_id": user._id },
{
"$addToSet": {
"lectures.physics.topic": {
"name": "Fluid Mechanics",
"day": "Monday",
"faculty": "Nancy Wagner"
}
}
},
{ "returnOriginal": false },
function(err,user) {
callback(err,user);
}
);
}
],
function(err,user) {
if (err) throw err;
console.log("Modified: %s", logger(user));
mongoose.disconnect();
}
);
这与结果完美配合:
Saved: {
"__v": 0,
"name": "bob",
"_id": "55cda1f5b5ee8b870e2f53bd"
}
Modified: {
"lastErrorObject": {
"updatedExisting": true,
"n": 1
},
"value": {
"_id": "55cda1f5b5ee8b870e2f53bd",
"name": "bob",
"__v": 0,
"lectures": {
"physics": {
"topic": [
{
"name": "Fluid Mechanics",
"day": "Monday",
"faculty": "Nancy Wagner"
}
]
}
}
},
"ok": 1
}
您需要在这里小心,因为本机驱动程序方法不像猫鼬方法那样知道连接状态。因此,您需要确保已通过较早触发的“mongoose”方法建立连接,或者将您的应用程序包装在连接事件中,如下所示:
mongoose.connection.on("connect",function(err) {
// start app in here
});
至于“错误”,请查看此列表中的日志记录输出:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/school');
mongoose.set('debug',true);
var userSchema = new Schema({
name: {
type: String,
required: true
},
lectures: { type: Schema.Types.Mixed }
});
var User = mongoose.model( "User", userSchema );
function logger(data) {
return JSON.stringify(data, undefined, 2);
}
async.waterfall(
[
function(callback) {
User.remove({},function(err) {
callback(err);
});
},
function(callback) {
console.log("here");
var user = new User({ "name": "bob" });
user.save(function(err,user) {
callback(err,user);
});
},
function(user,callback) {
console.log("Saved: %s", logger(user));
User.findByIdAndUpdate(
user._id,
{
"$addToSet": {
"lectures.physics.topic": {
"name": "Fluid Mechanics",
"day": "Monday",
"faculty": "Nancy Wagner"
}
}
},
{ "new": true },
function(err,user) {
callback(err,user);
}
);
}
],
function(err,user) {
if (err) throw err;
console.log("Modified: %s", logger(user));
mongoose.disconnect();
}
);
以及使用猫鼬日志记录的记录输出:
Mongoose: users.remove({}) {}
here
Mongoose: users.insert({ name: 'bob', _id: ObjectId("55cda2d2462283c90ea3f1ad"), __v: 0 })
Saved: {
"__v": 0,
"name": "bob",
"_id": "55cda2d2462283c90ea3f1ad"
}
Mongoose: users.findOne({ _id: ObjectId("55cda2d2462283c90ea3f1ad") }) { new: true, fields: undefined }
Modified: {
"_id": "55cda2d2462283c90ea3f1ad",
"name": "bob",
"__v": 0
}
那么在真正的“What the Fudge?” 风格中,有一个电话到.findOne()?这不是被问到的。此外,数据库中当然没有任何改变,因为调用错误。所以即使是这里的{ "new": true } 也是多余的。
这发生在所有级别的“混合”架构类型中。
我个人不会像这样嵌套在“对象”中,而只是将您的“对象键”作为附加属性作为标准数组的一部分。 MongoDB 和 mongoose 都乐此不疲,这样的结构查询信息也容易很多。
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/school');
mongoose.set('debug',true);
var lectureSchema = new Schema({
"subject": String,
"topic": String,
"day": String,
"faculty": String
});
var userSchema = new Schema({
name: {
type: String,
required: true
},
lectures: [lectureSchema]
});
var User = mongoose.model( "User", userSchema );
function logger(data) {
return JSON.stringify(data, undefined, 2);
}
async.waterfall(
[
function(callback) {
User.remove({},function(err) {
callback(err);
});
},
function(callback) {
console.log("here");
var user = new User({ "name": "bob" });
user.save(function(err,user) {
callback(err,user);
});
},
function(user,callback) {
console.log("Saved: %s", logger(user));
User.findByIdAndUpdate(
user._id,
{
"$addToSet": {
"lectures": {
"subject": "physics",
"topic": "Fluid Mechanics",
"day": "Monday",
"faculty": "Nancy Wagner"
}
}
},
{ "new": true },
function(err,user) {
callback(err,user);
}
);
}
],
function(err,user) {
if (err) throw err;
console.log("Modified: %s", logger(user));
mongoose.disconnect();
}
);
输出:
Mongoose: users.remove({}) {}
here
Mongoose: users.insert({ name: 'bob', _id: ObjectId("55cda4dc40f2a8fb0e5cdf8b"), lectures: [], __v: 0 })
Saved: {
"__v": 0,
"name": "bob",
"_id": "55cda4dc40f2a8fb0e5cdf8b",
"lectures": []
}
Mongoose: users.findAndModify({ _id: ObjectId("55cda4dc40f2a8fb0e5cdf8b") }) [] { '$addToSet': { lectures: { faculty: 'Nancy Wagner', day: 'Monday', topic: 'Fluid Mechanics', subject: 'physics', _id: ObjectId("55cda4dc40f2a8fb0e5cdf8c") } } } { new: true, upsert: false, remove: false }
Modified: {
"_id": "55cda4dc40f2a8fb0e5cdf8b",
"name": "bob",
"__v": 0,
"lectures": [
{
"faculty": "Nancy Wagner",
"day": "Monday",
"topic": "Fluid Mechanics",
"subject": "physics",
"_id": "55cda4dc40f2a8fb0e5cdf8c"
}
]
}
这样就可以正常工作了,您无需为了使其正常工作而深入研究本机方法。
数组的属性使得查询和过滤以及跨数据的“聚合”信息变得非常容易,对于所有这些 MongoDB 来说,它都喜欢使用“严格路径”来引用所有信息。否则,您只会区分“特定键”,如果不提及所有可能的“键组合”,就无法索引或真正搜索这些键。
这样的属性是更好的选择。这里没有错误。