我正在尝试使用mongoose在我的User
集合中获取子文档。我在其官方网站上关注了Mongoose Sub Document。它写道:
每个文档都有一个_id。 DocumentArrays有一个特殊的id方法,用于通过_id查找文档。
var doc = parent.children.id(id);
这是我的代码:
exports.editAccount = function(req, res) {
var user = new User(req.user);
var newAccount = new Account(req.body);
console.log("Account:" + newAccount._id); // Gave me 53bf93d518254f880c000009
var account = user.accounts.id(newAccount._id);
console.log("Account" + account); // Never been printed
};
console.log("Account" + account);
从未打印过。我不知道发生了什么。我试过很多不同的方法,然而,仍然无法弄明白。任何帮助将不胜感激。
用户收藏:
{
"__v" : 1,
"_id" : ObjectId("53bcf3e6fbf5adf10c000001"),
"accounts" : [
{
"accountId" : "123456789",
"type" : "Saving account",
"balance" : 100,
"_id" : ObjectId("53bf93d518254f880c000009")
}
]
}
我
答案 0 :(得分:1)
不太清楚你是如何定义Schema的,或者甚至是模型实例,但实际上你需要的只是:
var accountSchema = new Schema({
"accountId": String,
"type": { "type": String, "enum": ["Saving Account", "Checking Account"] },
"balance": { "type": Number, "default": 0 }
]);
var userSchema = new Schema({
"accounts": [accountSchema]
]);
var User = mongoose.model( "User", userSchema );
然后,当您想要向用户添加一个帐户时,假设您的输入与第一个变量声明匹配:
var input = {
"accountId": "123456789",
"type": "Savings Account",
};
User.findByIdAndUpdate(
userId,
{ "$push": { "accounts": input } },
function(err,user) {
// work with result in here
}
);
这确实绕过了验证和其他钩子之类的东西,但在与MongoDB通信方面效率更高。
如果您确实需要验证和/或其他功能,那么您使用.find()
变体并发布.save()
方法。
User.findById(userId,function(err,user) {
if (err) throw err; // or handle better
user.accounts.push( input );
user.save(function(err, user) {
// more handling
});
]);
要修改文档,那么你也会做同样的事情。通过最有效的MongoDB方式:
var input = {
accountId: "123456789",
amount: 100
};
User.findOneAndUpdate(
{ "_id": userId, "accounts.accountId": input.accountId },
{ "$inc": { "accounts.$.balance": input.amount } },
function(err,user) {
// handle result
}
);
或者再次需要Mongoose钩子和/或验证来应用:
User.findById(userId,function(err,user) {
if (err) throw err; // or handle otherwise
user.accounts.forEach(function(account) {
if ( account.accountId === input.accountId )
account.balance += input.balance;
});
user.save(function(err,user) {
// handle things
});
);
请记住,这些东西都是"数组",您可以使用MongoDB方式或JavaScript方式处理它们。这取决于你选择的地方"验证"你的意见。
更多代码说明用法不正确的地方:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/child');
var accountSchema = new Schema({
"accountId": String,
"type": { "type": String },
"balance": { "type": Number, "default": 0 }
});
var userSchema = new Schema({
"accounts": [accountSchema]
});
var User = mongoose.model( "User", userSchema );
async.waterfall([
function(callback) {
User.create({},function(err,user) {
if (err) throw err;
console.log(
"Created:\n%s\n",
JSON.stringify( user, undefined, 4 )
);
callback(null,user);
});
},
function(user,callback) {
var account = user.accounts.create({
"accountId": "123456789",
"type": "Savings"
});
console.log(
"Account is:\n%s\n",
JSON.stringify( account, undefined, 4 )
);
console.log(
"User is still:\n%s\n",
JSON.stringify( user, undefined, 4 )
);
user.accounts.push( account );
console.log(
"User Changed:\n%s\n",
JSON.stringify( user, undefined, 4 )
);
User.findById(user.id,function(err,saved) {
if (err) throw err;
console.log(
"Persisted is still:\n%s\n",
saved
);
user.save(function(err,user) {
if (err) throw err;
callback(null,user,account);
});
});
},
function(user,account,callback) {
User.findById(user.id,function(err,saved) {
if (err) throw err;
console.log(
"Persisted is now:\n%s\n",
saved
);
var item = user.accounts.id(account.id);
console.log(
"Item is:\n%s\n",
item
);
callback();
});
}
],function(err) {
process.exit();
});
结果:
Created:
{
"__v": 0,
"_id": "53c08ab51083d1fe3852becc",
"accounts": []
}
Account is:
{
"accountId": "123456789",
"type": "Savings",
"_id": "53c08ab51083d1fe3852becd",
"balance": 0
}
User is still:
{
"__v": 0,
"_id": "53c08ab51083d1fe3852becc",
"accounts": []
}
User Changed:
{
"__v": 0,
"_id": "53c08ab51083d1fe3852becc",
"accounts": [
{
"accountId": "123456789",
"type": "Savings",
"_id": "53c08ab51083d1fe3852becd",
"balance": 0
}
]
}
Persisted is still:
{ _id: 53c08ab51083d1fe3852becc, __v: 0, accounts: [] }
Persisted is now:
{ _id: 53c08ab51083d1fe3852becc,
__v: 1,
accounts:
[ { accountId: '123456789',
type: 'Savings',
_id: 53c08ab51083d1fe3852becd,
balance: 0 } ] }
Item is:
{ accountId: '123456789',
type: 'Savings',
_id: 53c08ab51083d1fe3852becd,
balance: 0 }