过滤器嵌套或嵌套在 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
        });
    });

我正在寻找一种方法来删除没有 sectionssubsystems。 经过几个小时的搜索,我认为没有办法根据嵌套 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;
    }
});

它删除所有没有 sectionssubsystems