Mongoose.js - 与平时不同的人口
Mongoose.js - different population than usual
我有以下来自 collection "main" 的简化文档:
{
_id: 120,
name: "Main1",
prop1: "val",
menuId: 5
}
这是我的 "menu" collection:
的简化文档
{
_id: 5,
menuItems: [an array of elements here],
menuProperties: {an object here}
}
是否可以使用 mongoose.js 将 "menu" 文档填充到 "main" 文档中,从而产生以下模型 object:
{
_id: 120,
name: "Main1",
prop1: "val",
menuItems: [an array of elements here],
menuProperties: {an object here}
}
我现在能做到的是:
{
_id: 120,
name: "Main1",
prop1: "val",
menuId: {
menuItems: [an array of elements here],
menuProperties: {an object here}
}
}
我没有添加这些方案,因为它们非常简单并且将包含 menuId
的 ref
。
谢谢!
有很多方法可以做到这一点。你总是可以做这样的事情(注意,你没有 post 你的模式所以我编了名字):
//get every document in menu collection
Menu.find({}).exec(function(err,all_menuItems){
if (err) {throw err};
//for all documents in them meny collection
//find docuement in main collection and update
all_menuItems.forEach(function(item){
//wrapping in closure since doing forEach over async function
function(){
Main.findOne({_id:item._id}).exec(function(err,mainItem){
if (err) {throw err};
//set properties
mainItem.menuItems = item.menuItems;
menuItem.menuProperties = item.menuProperties;
//save document
Main.save(mainItem)
})
}(item)
})
})
此外,mongoose 作为内置填充方法可用于执行此操作。您可以在此处找到该文档。 http://mongoosejs.com/docs/populate.html.
使用 populate 可能比循环一堆异步调用(或重写上面的代码以同步处理更新)更好。但是您可以处理对您的数据库最有意义的任何方式。
一种方法是从填充结果中删除 menuId
,然后将 menuItem
和 menuProperties
添加到填充结果中。这是示例代码,
Main.find()
.populate('menuId', 'menuItem menuProperties -_id', 'Menu')
.exec(function(err, docs){
if (err)
console.log(err);
else {
var rets = [];
docs.forEach(function(doc) {
// converts the mongoose document into a plain javascript object
doc = doc.toJSON();
// add menuItem key
if (doc.menuId && doc.menuId.menuItem) {
doc.menuItem = doc.menuId.menuItem;
}
// add menuProperties key
if (doc.menuId && doc.menuId.menuProperties) {
doc.menuProperties = doc.menuId.menuProperties;
// remove the menuId object
delete doc.menuId
}
rets.push(doc);
});
console.log(rets);
}
});
使用架构测试
var MainSchema = new mongoose.Schema({
name: String,
prop1: String,
menuId: Number
});
var MenuSchema = new mongoose.Schema({
_id: Number,
menuItem: [String],
menuProperties: {k: String}
});
var Main = mongoose.model('Main', MainSchema);
var Menu = mongoose.model('Menu', MenuSchema);
结果是
[ { _id: 56fa39b4924d1254272ac3f1,
name: 'main1',
prop1: 'val',
__v: 0,
menuItem: [ 't1', 't2' ],
menuProperties: { k: 'p1' } } ]
我有以下来自 collection "main" 的简化文档:
{
_id: 120,
name: "Main1",
prop1: "val",
menuId: 5
}
这是我的 "menu" collection:
的简化文档{
_id: 5,
menuItems: [an array of elements here],
menuProperties: {an object here}
}
是否可以使用 mongoose.js 将 "menu" 文档填充到 "main" 文档中,从而产生以下模型 object:
{
_id: 120,
name: "Main1",
prop1: "val",
menuItems: [an array of elements here],
menuProperties: {an object here}
}
我现在能做到的是:
{
_id: 120,
name: "Main1",
prop1: "val",
menuId: {
menuItems: [an array of elements here],
menuProperties: {an object here}
}
}
我没有添加这些方案,因为它们非常简单并且将包含 menuId
的 ref
。
谢谢!
有很多方法可以做到这一点。你总是可以做这样的事情(注意,你没有 post 你的模式所以我编了名字):
//get every document in menu collection
Menu.find({}).exec(function(err,all_menuItems){
if (err) {throw err};
//for all documents in them meny collection
//find docuement in main collection and update
all_menuItems.forEach(function(item){
//wrapping in closure since doing forEach over async function
function(){
Main.findOne({_id:item._id}).exec(function(err,mainItem){
if (err) {throw err};
//set properties
mainItem.menuItems = item.menuItems;
menuItem.menuProperties = item.menuProperties;
//save document
Main.save(mainItem)
})
}(item)
})
})
此外,mongoose 作为内置填充方法可用于执行此操作。您可以在此处找到该文档。 http://mongoosejs.com/docs/populate.html.
使用 populate 可能比循环一堆异步调用(或重写上面的代码以同步处理更新)更好。但是您可以处理对您的数据库最有意义的任何方式。
一种方法是从填充结果中删除 menuId
,然后将 menuItem
和 menuProperties
添加到填充结果中。这是示例代码,
Main.find()
.populate('menuId', 'menuItem menuProperties -_id', 'Menu')
.exec(function(err, docs){
if (err)
console.log(err);
else {
var rets = [];
docs.forEach(function(doc) {
// converts the mongoose document into a plain javascript object
doc = doc.toJSON();
// add menuItem key
if (doc.menuId && doc.menuId.menuItem) {
doc.menuItem = doc.menuId.menuItem;
}
// add menuProperties key
if (doc.menuId && doc.menuId.menuProperties) {
doc.menuProperties = doc.menuId.menuProperties;
// remove the menuId object
delete doc.menuId
}
rets.push(doc);
});
console.log(rets);
}
});
使用架构测试
var MainSchema = new mongoose.Schema({
name: String,
prop1: String,
menuId: Number
});
var MenuSchema = new mongoose.Schema({
_id: Number,
menuItem: [String],
menuProperties: {k: String}
});
var Main = mongoose.model('Main', MainSchema);
var Menu = mongoose.model('Menu', MenuSchema);
结果是
[ { _id: 56fa39b4924d1254272ac3f1,
name: 'main1',
prop1: 'val',
__v: 0,
menuItem: [ 't1', 't2' ],
menuProperties: { k: 'p1' } } ]