You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js Mongoose嵌套数组按对象属性筛选数据求助

Fixing Nested Array Filtering for Valid Categories and Sub-Services in Mongoose

Hey there! I get that as a Node.js/Mongoose newbie, filtering nested arrays can be tricky. Let's figure out how to fix your query so you only get the valid categories and their valid sub-services.

The issue with your current find() query is that MongoDB only uses those valid: true conditions to select which Vendor documents to return—it doesn't filter out individual invalid elements inside the categories or sub_services arrays. To achieve your desired result, we need to use MongoDB's aggregation framework, which lets us clean up nested arrays directly in the database.


This approach does all the filtering on the database side, which is much more efficient than fetching extra data and filtering it in your code. Here's the revised query:

router.get('/get_service_details', function(req, res) {
  Vendor.aggregate([
    // Step 1: Match the specific Vendor document you need
    { $match: { _id: req.user._id } },
    // Step 2: Filter out invalid categories
    {
      $project: {
        services: {
          meta_data: "$services.meta_data", // Keep your meta_data intact
          categories: {
            $filter: {
              input: "$services.categories",
              as: "category",
              cond: { $eq: ["$$category.valid", true] }
            }
          }
        }
      }
    },
    // Step 3: Filter invalid sub-services from remaining categories
    {
      $addFields: {
        "services.categories": {
          $map: {
            input: "$services.categories",
            as: "category",
            in: {
              service_category: "$$category.service_category",
              valid: "$$category.valid",
              sub_services: {
                $filter: {
                  input: "$$category.sub_services",
                  as: "sub",
                  cond: { $eq: ["$$sub.valid", true] }
                }
              }
            }
          }
        }
      }
    }
  ])
  .exec(function(err, result) {
    if (err) {
      console.log(err);
      return res.status(500).send(err);
    }
    // Aggregation returns an array—send the first (and only) matching document
    res.send(result[0]);
  });
});

Breakdown of How This Works:

  • $match: Narrows down to exactly the Vendor document linked to the current user, just like your original query.
  • First $project: Uses $filter to remove any categories where valid is false.
  • $addFields + $map: Iterates over each remaining valid category, then uses another $filter to strip out sub-services with valid: false. We reconstruct each category object to keep only the fields we need with the filtered sub-services.

Solution 2: Post-Query JavaScript Filtering (Simpler for Small Datasets)

If you're working with small datasets and prefer a more straightforward approach, you can fetch the full document first and filter the arrays in your code:

router.get('/get_service_details', function(req, res) {
  Vendor.findOne({ _id: req.user._id }, 'services')
    .exec(function(err, vendor) {
      if (err) {
        console.log(err);
        return res.status(500).send(err);
      }
      // Filter out invalid categories
      vendor.services.categories = vendor.services.categories.filter(category => category.valid);
      // Filter invalid sub-services for each valid category
      vendor.services.categories.forEach(category => {
        category.sub_services = category.sub_services.filter(sub => sub.valid);
      });
      res.send(vendor);
    });
});

Note: This method pulls the full document from the database first, so it's not ideal for large arrays. Stick with the aggregation approach if you expect your data to grow.


Either solution will give you your desired output: only valid categories with their valid sub-services.

内容的提问来源于stack exchange,提问作者Achira Shamal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:05:28