【问题标题】:MongoDB: filter by array size and total with aggregateMongoDB:按数组大小和总计过滤
【发布时间】:2021-09-13 20:22:18
【问题描述】:

我正在使用 聚合 查询。 如果出现以下情况,我需要退回文件:

  • “总计”不存在
  • 数组大小小于“总数”

所以隐藏所有数组等于到“total”的所有文档。

注意事项:

  • “容器”可以有不同的“子容器”
  • “subContainer”是动态键名
  • “总计”是可选的
  • “arr”大小

集合中的文档:

[
  {  // "container.subContainer2.arr" is lower then "total"
    "_id": 1,
    "title": "title1",
    "container": {
      "subContainer1": {
        "arr": [1, 2, 3]
      },
      "subContainer2": {
        "arr": [1]
      }
    },
    "total": 3
  },
  {  // "total" unknow
    "_id": 2,
    "title": "title2",
    "container": {
      "subContainer3": {
        "arr": [1, 2, 3, 4]
      }
    }
  },
  {  // both array size are equal to "total"
    "_id": 3,
    "title": "title3",
    "container": {
      "subContainer4": {
        "arr": [1, 2, 3, 4, 5]
      },
      "subContainer5": {
        "arr": [1, 2, 3, 4, 5]
      }
    },
    "total": 5
  }
]

输出:

[
  {
    "title": "title1"
  },
  {
    "title": "title2"
  }
]

【问题讨论】:

  • 什么数组大小应该小于“总”?任何subContainer 或所有subContainer 大小?
  • @NenadMilosavljevic 大小仅与“arr”数组有关。
  • 但是每个subContainer 都有一个arr 数组。它们应该都低于total 还是至少一个?
  • 是的,每个subContainer 至少有一个arr 数组。它们都可以是 lowerequal total.

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

首先我们用$addFields添加一些额外的字段 并使用地图创建包含arr 的数组 和sum 每个文档中arr 的大小并作为newField 如果"arr" size <= "total",则将状态字段创建为布尔值 和match 所有状态为:true 和项目标题的文档

db.collection.aggregate([
  {
    "$addFields": {
      "newField": {
        "$objectToArray": "$container"
      }
    }
  },
  {
    "$addFields": {
      "newField1": {
        "$map": {
          "input": "$newField",
          "as": "z",
          "in": {
            $size: "$$z.v.arr"
          }
        }
      }
    }
  },
  {
    "$addFields": {
      "newField": {
        "$sum": "$newField1"
      }
    }
  },
  {
    "$addFields": {
      "status": {
        $gte: [
          "$total",
          "$newField"
        ]
      }
    }
  },
  {
    $match: {
      status: true
    }
  },
  {
    $project: {
      title: 1,
      _id: 0
    }
  }
])

https://mongoplayground.net/p/PhkeJUCkE6d

【讨论】:

  • 感谢您的回答。我将$sum 更改为$min,将$gte 更改为$gt,因为我只想在arr 数组大小小于total 时才返回一个文档。当total 丢失时,它不会返回任何文档。
  • 你能解决问题吗?
  • 我认为你需要 arr 大小的总和,应该是总和
  • total 就像每个 arr 数组的大小限制。
  • 好的,如果我的回答能帮助你解决问题,感谢补票:)
【解决方案2】:

我使用$not 来检查total 是否存在(假)和$cond 来检查结果来解决这个问题。

[
  {
    "$addFields": {
      "newField": {
        "$objectToArray": "$container"
      }
    }
  },
  {
    "$addFields": {
      "newField1": {
        "$map": {
          "input": "$newField",
          "as": "z",
          "in": {
            "$size": "$$z.v.arr"
          }
        }
      }
    }
  },
  {
    "$addFields": {
      "newField": {
        "$min": "$newField1"
      }
    }
  },
  {
    "$addFields": {
      "status": {
        "$cond": [
          {
            "$not": [
              "$total"
            ]
          },
          true,
          {
            "$gt": [
              "$total",
              "$newField"
            ]
          }
        ]
      }
    }
  },
  {
    "$match": {
      "status": true
    }
  },
  {
    "$project": {
      "title": 1,
      "_id": 0
    }
  }
]

https://mongoplayground.net/p/qrSiAX88UFZ

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-03
    • 2018-06-03
    • 1970-01-01
    相关资源
    最近更新 更多