首页 > 解决方案 > 在 mongo 子子数组中过滤结果

问题描述

我有一些收藏品,比如我们:

[{
  "_id": ObjectId("604f3ae3194f2135b0ade569"),
  "parameters": [
    {
      "_id": ObjectId("602b7455f4b4bf5b41662ec1"),
      "name": "Purpose",
      "options": [
        {
          "id": ObjectId("602b764ff4b4bf5b41662ec2"),
          "name": "debug",
          "sel": false
        },
        {
          "id": ObjectId("602b767df4b4bf5b41662ec3"),
          "name": "performance",
          "sel": false
        },
        {
          "id": ObjectId("602b764ff4b4bf5b41662ec4"),
          "name": "security",
          "sel": false
        },
        {
          "id": ObjectId("602b767df4b4bf5b41662ec5"),
          "name": "Not Applicable",
          "sel": false
        }
      ],
      "type": "multiple"
    },
    {
      "_id": ObjectId("602b79d35d4a1333b8b6e5ba"),
      "name": "Organization",
      "options": [
        {
          "id": ObjectId("602b79d353c89933b8238325"),
          "name": "SW",
          "sel": false
        },
        {
          "id": ObjectId("602b79d353c89933b8238326"),
          "name": "HW",
          "sel": false
        }
      ],
      "type": "multiple"
    }
  ]
}]

参数最多为30。

我需要在 mongo 中实现一个“过滤器”集合。

如果我过滤一个或多个parameters._id,mongo 返回:

  1. 具有匹配options.sel的集合_idthis parameters._id
  2. 集合 _id 都options.sel等于falseofthis parameters._id
  3. 非返回集合 _id 如果parameters._id已设置options.name:"Not Applicable"为值options.sel:true

例如,如果我匹配parameters._id:ObjectId("602b7455f4b4bf5b41662ec1")和 this parameters.options.id:ObjectId("602b764ff4b4bf5b41662ec2"),我期望:

接下来我需要为更多参数制定这个规则。

我想为每个规则实现三个聚合......你有什么建议吗?

标签: mongodbmongodb-query

解决方案


有了@dheemanth-bath 的想法,我做了这个查询:

db.testCollection.aggregate([
    { $unwind: "$parameters" },
    {
        $match: {
            "parameters._id": ObjectId("602b7455f4b4bf5b41662ec1"),
        }
    },
    {
        $addFields: {
            match: {
                $filter: {
                    input: "$parameters.options",
                    as: "option",
                    cond: {
                        $and: [
                           { $eq: ["$$option.id", ObjectId('602b767df4b4bf5b41662ec5')] },
                           { $eq: ["$$option.sel", true] }
                        ]
                    }
                }
            },
            notDeclared: {
                $filter: {
                    input: "$parameters.options",
                    as: "option",
                    cond: {
                        $and: [
                           { $eq: ["$$option.name", "Not Applicable"]},
                           { $eq: ["$$option.sel", true] }
                        ]
                    }
                }
            }
        }
    }
])

这个想法是:在查询后计算未声明的元素的数量。如果 > 0 则浪费集合。否则计算匹配数,如果>0,则至少有一个元素可以匹配。

好的。但是我如何评估options.sel 的所有元素是否为假?

如果我检查另一个参数,我需要进行另一个聚合(一个用于参数)?


推荐阅读