gpt4 book ai didi

javascript - 用于在集合中获取子项和孙子项的 Mongoose 查询

转载 作者:行者123 更新时间:2023-11-30 11:40:37 25 4
gpt4 key购买 nike

我有什么:

我在 mongo 中有一个集合,其中有很多文档。该集合称为 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
})

但我不想要上面提到的东西。

我只想拥有一个集合,并且数据是相关的。

最佳答案

您需要分 3 个阶段完成:

  1. 首先通过他的_id查询得到John>
  2. 通过搜索以 John 的 id 作为他们的经理的用户来获取 John 的“ child ”
  3. 通过查询将 John 的 child 任何作为其经理的所有用户,获取 John 的“孙子”。 MongoDB $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 级后代。

您可以使用 co 库的 wrap 函数来执行此操作,如下所示:

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
});

注意:为确保没有重复项,您可以使用像 Set 这样的东西而不是 users 的数组,或者您可以将每个用户添加到 一个一个地检查用户,检查每个用户是否已经存在于 users 数组中。

关于javascript - 用于在集合中获取子项和孙子项的 Mongoose 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42832408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com