mongoDB在多个条件下计算深度嵌套的元素

k3bvogb1  于 2023-03-07  发布在  Go
关注(0)|答案(2)|浏览(75)

请帮帮忙,我需要找到count()的所有_a[]._p[]元素,这些元素至少具有以下之一:
_a[]._p[].s.d.t[].日期P =2022年和_a[]._p[].s.d.t[].tF=“否”
以及
_a[]._p[].s.c.t[].日期P =2022年和_a[]._p[].s.c.t[].tF=“N”
在以下类型文档中:

{
"_id": ObjectId("5c05984246a0201286d4b57a"),
f: "x",
"_a": [
  {
    "_p": [
      {
        "pid": 2,
        "s": {
          "d": {
            "t": [
              {
                id: 1,
                "dateP": "20200-09-20",
                
              },
              {
                id: 2,
                "dateP": "2022-09-20",
                "tF": "N"
              }
            ]
          },
          "c": {
            "t": [
              {
                id: 3,
                "dateP": "20300-09-22"
              },
              {
                id: 4,
                "dateP": "2022-09-23",
                "tF": "N"
              }
            ]
          }
        }
      }
    ]
  }
]
}

在我的尝试中,我只能计算部分匹配条件的文档,但不确定当有更多嵌套数组时这是否正确,也不确定如何更快地计算_a中的_p元素:

db.collection.count({ "_a._p.s.c.t":{ $elemMatch:{ tF:"N" , dateP: /^2022/i  }  } })

Playground的预期结果需要如下所示:

{ total: 1 }

由于具有id为2的s.d.t和id为4的s.c.t的_a._p符合上述条件
Playground

zujrkrfu

zujrkrfu1#

这里有一种不用"$unwind"也能做到的方法,尽管"$reduce"的嵌套层次看起来很容易出错,我希望你在使用它之前用大量的数据测试一下。

db.collection.aggregate([
  {
    "$match": {
      "_a._p.s.d.t": {
        "$elemMatch": {
          "dateP": {"$regex": "^2022"},
          "tF": "N"
        }
      },
      "_a._p.s.c.t": {
        "$elemMatch": {
          "dateP": {"$regex": "^2022"},
          "tF": "N"
        }
      }
    }
  },
  {
    "$project": {
      "ap": "$_a._p"
    }
  },
  {
    "$project": {
      "docCount": {
        "$reduce": {
          "input": "$ap",
          "initialValue": 0,
          "in": {
            "$sum": [
              "$$value",
              {
                "$reduce": {
                  "input": "$$this",
                  "initialValue": 0,
                  "in": {
                    "$sum": [
                      "$$value",
                      {
                        "$cond": [
                          {
                            "$and": [
                              {
                                "$reduce": {
                                  "input": "$$this.s.c.t",
                                  "initialValue": false,
                                  "in": {
                                    "$or": [
                                      "$$value",
                                      {
                                        "$and": [
                                          {"$eq": ["$$this.tF", "N"]},
                                          {
                                            "$regexMatch": {
                                              "input": "$$this.dateP",
                                              "regex": "^2022"
                                            }
                                          }
                                        ]
                                      }
                                    ]
                                  }
                                }
                              },
                              {
                                "$reduce": {
                                  "input": "$$this.s.d.t",
                                  "initialValue": false,
                                  "in": {
                                    "$or": [
                                      "$$value",
                                      {
                                        "$and": [
                                          {"$eq": ["$$this.tF", "N"]},
                                          {
                                            "$regexMatch": {
                                              "input": "$$this.dateP",
                                              "regex": "^2022"
                                            }
                                          }
                                        ]
                                      }
                                    ]
                                  }
                                }
                              }
                            ]
                          },
                          1,
                          0
                        ]
                      }
                    ]
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    "$group": {
      "_id": null,
      "totalCount": {"$sum": "$docCount"}
    }
  }
])

试试看mongoplayground.net

8yoxcaq7

8yoxcaq72#

解应该是这样的

  • 更新:仅计数元素 *
db.collection.aggregate([
  {
    $project: {
      sct: {
        "$size": "$_a._p.s.c.t"
      },
      scd: {
        "$size": "$_a._p.s.d.t"
      }
    }
  },
  
])

MONGO_PALYGROUND

相关问题