Javascript 用于获取集合中的子代和孙子代的Mongoose查询
我所拥有的: 我在mongo收集了很多文件。该集合称为Javascript 用于获取集合中的子代和孙子代的Mongoose查询,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,我所拥有的: 我在mongo收集了很多文件。该集合称为Users。出于示例目的,我展示了所有的7条记录 { _id: _______________________, name: Mary }, { _id: _______________________, name: John, manager: objectId("id of Mary"); }, { _id: _______________________, name: Ti
Users
。出于示例目的,我展示了所有的7条记录
{
_id: _______________________,
name: Mary
},
{
_id: _______________________,
name: John,
manager: objectId("id of Mary");
},
{
_id: _______________________,
name: Tim,
manager: objectId("id of John");
},
{
_id: _______________________,
name: Tom,
manager: objectId("id of John");
},
{
_id: _______________________,
name: Henry,
manager: objectId("id of Tim");
},
{
_id: _______________________,
name: Mark,
manager: objectId("id of Henry");
},
{
_id: _______________________,
name: Todd,
manager: objectId("id of Mary");
}
通过查看上述数据,您可以看到如下关系:
Mary
|
-------------------------------------
| |
John Todd
|
--------------------------
| |
Tim Tom
|
Henry
|
Mark
我想要什么:
我需要一个mongoose查询,它返回所有记录及其子项和子项。例如,如果我想让所有用户都在John下,包括John,那么我的输出应该如下所示:
{
_id: _______________________,
name: John,
manager: objectId("id of Mary");
},
{
_id: _______________________,
name: Tim,
manager: objectId("id of John");
},
{
_id: _______________________,
name: Tom,
manager: objectId("id of John");
},
{
_id: _______________________,
name: Henry,
manager: objectId("id of Tim");
},
{
_id: _______________________,
name: Mark,
manager: objectId("id of Henry");
}
我不想要的:
我知道数据是关系型的,所以有些人可能会建议我使用关系型数据库。但现在我正在尝试学习mongodb和Node.js。所以,我想继续使用mongodb
我还知道,有一个集合可以保存以下所有数据:
var ManagerSchema = new Schema({
manager_name: String,
users: [users]
}
var UserSchema = new Schema({
user_name: String
})
但是我不想要上面提到的东西
我只希望只有一个集合,数据将是相关的。您需要分三个阶段进行:
\u id
$in
操作符在这里很有用const idOfjohn = '1234567890abcdef';
let john, children, grandchildren; // initialise variables
Users.findById(idOfjohn) // find John
.then(user => {
john = user; // assign to variable with wider scope
return Users.find({ manager: idOfjohn }); // find users whose manager is John
})
.then(users => {
children = users;
const childrenIDs = users.map(user => user._id); // make array of IDs
return Users.find({ manager: { $in: childrenIDs } }); // find users whose managers have John as a manager
})
.then(users => {
grandchildren = users;
const all = [john]
.concat(children)
.concat(grandchildren); // create a single array
console.log(all); // or do whatever
});
编辑
OP澄清说他需要n级的后代
您可以使用库函数执行此操作,如下所示:
const { wrap } = require('co');
const findWithDescendants = wrap(function*(topUserId, generations) {
const topUser = yield Users.findById(topUserId); // get John himself
let users = [topUser]; // will hold all users
let ids = [topUserId]; // will hold IDs to search in
for (let i = 0; i < generations; i++) {
const thisLevelUsers = yield Users.find({ manager: { $in: ids } });
ids = thisLevelUsers.map(user => user._id); // replace with new IDs
users = users.concat(thisLevelUsers); // add new users
}
return users;
});
findWithDescendants(idOfjohn, 3)
.then(users => {
console.log(users); // or do whatever
});
const{wrap}=require('co');
const findWithDescents=wrap(函数*(topUserId,代){
const topUser=yield Users.findById(topUserId);//获取John本人
let users=[topUser];//将容纳所有用户
let ids=[topUserId];//将保留要在其中搜索的ID
for(设i=0;iuser.\u id);//替换为新id
users=users.concat(thisLevelUsers);//添加新用户
}
返回用户;
});
FindWith后代(idOfjohn,3)
。然后(用户=>{
console.log(用户);//或执行任何操作
});
注意:为确保不存在重复项,您可以为
用户
使用类似于数组的内容,也可以将每个用户逐个添加到用户
,检查每个操作符是否已经出现在用户数组中。看看mongodb 3.4I中引入的操作符,我还没有使用graphLookup,这可能是最好的解决方案。否则,我认为唯一可以做到这一点的方法是在单独的查询中进行查询,如果您愿意,我可以提供帮助。@felix我已经在文档中查看了图形查找。在我看来,图形查找返回的是继承人的体系结构数据。但我想要问题中提到的平面数据。@Aron我想看看你的答案。@Vishal我的答案有用吗?我希望它适用于第N个孩子。所以我不认为我会使用你给出的代码。谢谢你的帮助。我更新了我的答案以检索n个级别的深层次。谢谢你的编辑。我将检查它并告诉您是否需要任何更改/如果在const topUser=..之后在findWithDescents函数中输入console.log(topUser),那么我将获得John的所有直接子代。但就在returnusers语句之前,如果我是console.log(users);那么我就不会让任何用户登录。控制台中没有错误。我不知道为什么它会这样做。好的,我会尝试自己实现它。但是为什么我得到两个数组呢?我的意思是输出的模式是:[[{Tim object},{Tom object}],{Tim object},{Tom object},{Henry object}]
。我还没有插入标记记录。还有一件事。输出中没有约翰的记录。