过滤器嵌套或嵌套在 Mongoose 填充中
Filter nested of nested in Mongoose Populate
我有一个看起来像这样的对象:(这是 Mongoose 查询的输出)
let systems = [
{
"maxUserLevel": 1,
"subsystems": [
{
"sections": [],
"name": "apple"
},
{
"sections": [
{
"name": "banana"
}
],
"name": "sun",
},
{
"sections": [],
"name": "orange"
}
],
"systemID": "12345"
},
{
"maxUserLevel": 3,
"subsystems": [
{
"sections": [],
"name": "blue"
},
{
"sections": [
{
"name": "pink"
}
],
"name": "red",
},
],
"systemID": "15654"
}];
Mongoose 查询:
this.model.System.find({username: user.username}, {
_id: 0,
allowedOrganizations: 0,
name: 0,
updatedAt: 0,
createdAt: 0,
versionKey: 0
})
.populate(
{
path: "subsystems",
populate: {
path: "sections",
select: "name -_id",
match: {
allowedUsers: user.id
}
},
select: "name metadata -_id",
}
)
.exec((error, systems) => {
return res.status(200).json({
data: systems,
success: true
});
});
我正在寻找一种方法来删除没有 sections
的 subsystems
。
经过几个小时的搜索,我认为没有办法根据嵌套 populate
过滤 populate
,所以我尝试了一些这样的方法:
if (systems.subsystems.length > 0) {
let test = [];
systems.subsystems.forEach((value, index) => {
if (value.sections.length !== 0) {
test[index] = value;
}
if (systems.subsystems.length === index + 1) {
return test;
}
})
}
但我不确定这是不是正确的方法。
您可以像这样对 $filter 使用聚合查询:
db.collection.aggregate([
{
"$project": {
"_id": 1,
"maxUserLevel": 1,
"subsystems": {
"$filter": {
"input": "$subsystems",
"as": "s",
"cond": {
"$ne": [
"$$s.sections",
[]
]
}
}
}
}
}
])
示例here
您的查询还应该包含一个 $match
阶段(就像您的 find
阶段)和 $lookup
.
我不确定这是最好的方法,但它解决了我的问题:
const _ = require('lodash');
systems.forEach((value, index) => {
systems[index].subsystems = _.filter(value.subsystems,
item => !item.sections.length == 0
);
if (systems.length === index + 1) {
return systems;
}
});
它删除所有没有 sections
的 subsystems
。
我有一个看起来像这样的对象:(这是 Mongoose 查询的输出)
let systems = [
{
"maxUserLevel": 1,
"subsystems": [
{
"sections": [],
"name": "apple"
},
{
"sections": [
{
"name": "banana"
}
],
"name": "sun",
},
{
"sections": [],
"name": "orange"
}
],
"systemID": "12345"
},
{
"maxUserLevel": 3,
"subsystems": [
{
"sections": [],
"name": "blue"
},
{
"sections": [
{
"name": "pink"
}
],
"name": "red",
},
],
"systemID": "15654"
}];
Mongoose 查询:
this.model.System.find({username: user.username}, {
_id: 0,
allowedOrganizations: 0,
name: 0,
updatedAt: 0,
createdAt: 0,
versionKey: 0
})
.populate(
{
path: "subsystems",
populate: {
path: "sections",
select: "name -_id",
match: {
allowedUsers: user.id
}
},
select: "name metadata -_id",
}
)
.exec((error, systems) => {
return res.status(200).json({
data: systems,
success: true
});
});
我正在寻找一种方法来删除没有 sections
的 subsystems
。
经过几个小时的搜索,我认为没有办法根据嵌套 populate
过滤 populate
,所以我尝试了一些这样的方法:
if (systems.subsystems.length > 0) {
let test = [];
systems.subsystems.forEach((value, index) => {
if (value.sections.length !== 0) {
test[index] = value;
}
if (systems.subsystems.length === index + 1) {
return test;
}
})
}
但我不确定这是不是正确的方法。
您可以像这样对 $filter 使用聚合查询:
db.collection.aggregate([
{
"$project": {
"_id": 1,
"maxUserLevel": 1,
"subsystems": {
"$filter": {
"input": "$subsystems",
"as": "s",
"cond": {
"$ne": [
"$$s.sections",
[]
]
}
}
}
}
}
])
示例here
您的查询还应该包含一个 $match
阶段(就像您的 find
阶段)和 $lookup
.
我不确定这是最好的方法,但它解决了我的问题:
const _ = require('lodash');
systems.forEach((value, index) => {
systems[index].subsystems = _.filter(value.subsystems,
item => !item.sections.length == 0
);
if (systems.length === index + 1) {
return systems;
}
});
它删除所有没有 sections
的 subsystems
。