首页 > 解决方案 > 如何在 Mongodb 中只获得多个计数?

问题描述

我试图只从一个看起来像这样的集合中的多个文档中获取多个计数值,(基本上我想计算来自 4 个方向的数量)

{
    "empno": 1500,
    "province": "North"
}
{
    "empno": 1600,
    "province": "West"
}

早期我找到了解决方案并实施了以下查询;

([
  { "$facet": {
     "N": [
    { "$match": { "province": "North" }},
    { "$count": "N" }
    ],
    "E": [
    { "$match": { "province": "East" }},
    { "$count": "E" }
    ],
    "S": [
    { "$match": { "province": "South" }},
    { "$count": "S" }
    ],
    "W": [
    { "$match": { "province": "West" }},
    { "$count": "W" }
    ]
  }},
    { "$project": {
    "N": { "$arrayElemAt": ["$N.N", 0] },
    "E": { "$arrayElemAt": ["$E.E", 0] },
    "S": { "$arrayElemAt": ["$S.S", 0] },
    "W": { "$arrayElemAt": ["$W.W", 0] },
  }}
  ]) 

我得到的输出是

{ N: 1, W: 1 }

我怎样才能得到只有没有键的值,而且我希望空的空白字段为 0。像这样;

 {1, 0, 0, 1}

标签: mongodbmongodb-query

解决方案


刻面

询问

  • 按 null 分组,是您需要添加以获取计数的内容

测试代码在这里

db.collection.aggregate([
  {
    "$facet": {
      "g0": [
        {
          "$match": {
            "province": {
              "$eq": "North"
            }
          }
        },
        {
          "$group": {
            "_id": null,
            "count": {
              "$sum": 1
            }
          }
        },
        {
          "$project": {
            "_id": 0
          }
        }
      ],
      "g1": [
        {
          "$match": {
            "province": {
              "$eq": "East"
            }
          }
        },
        {
          "$group": {
            "_id": null,
            "count": {
              "$sum": 1
            }
          }
        },
        {
          "$project": {
            "_id": 0
          }
        }
      ],
      "g2": [
        {
          "$match": {
            "province": {
              "$eq": "South"
            }
          }
        },
        {
          "$group": {
            "_id": null,
            "count": {
              "$sum": 1
            }
          }
        },
        {
          "$project": {
            "_id": 0
          }
        }
      ],
      "g3": [
        {
          "$match": {
            "province": {
              "$eq": "West"
            }
          }
        },
        {
          "$group": {
            "_id": null,
            "count": {
              "$sum": 1
            }
          }
        },
        {
          "$project": {
            "_id": 0
          }
        }
      ]
    }
  },
  {
    "$set": {
      "data": {
        "$map": {
          "input": {
            "$objectToArray": "$$ROOT"
          },
          "in": {
            "$cond": [
              {
                "$eq": [
                  "$$d.v",
                  []
                ]
              },
              0,
              {
                "$let": {
                  "vars": {
                    "m": {
                      "$arrayElemAt": [
                        "$$d.v",
                        0
                      ]
                    }
                  },
                  "in": "$$m.count"
                }
              }
            ]
          },
          "as": "d"
        }
      }
    }
  },
  {
    "$project": {
      "data": 1
    }
  }
])

团体

询问

  • 使用组而不是方面(方面就像每个字段 1 个聚合)
  • 每个组都有其索引(来自数组),一些索引将丢失(因为不存在文档)
  • 添加一个包含所有索引且 count=0 的零数据字段(见下文)
  • 添加到零数据,找到的数据(存在于集合中的数据,我们为它们设置了组)其余的保持 count=0

测试代码在这里

db.collection.aggregate([
  {
    "$group": {
      "_id": {
        "$switch": {
          "branches": [
            {
              "case": {
                "$eq": [
                  "$province",
                  "North"
                ]
              },
              "then": {
                "index": 0,
                "province": "North"
              }
            },
            {
              "case": {
                "$eq": [
                  "$province",
                  "East"
                ]
              },
              "then": {
                "index": 1,
                "province": "East"
              }
            },
            {
              "case": {
                "$eq": [
                  "$province",
                  "South"
                ]
              },
              "then": {
                "index": 2,
                "province": "South"
              }
            },
            {
              "case": {
                "$eq": [
                  "$province",
                  "West"
                ]
              },
              "then": {
                "index": 3,
                "province": "West"
              }
            }
          ],
          "default": {
            "index": 5
          }
        }
      },
      "count": {
        "$sum": 1
      }
    }
  },
  {
    "$group": {
      "_id": null,
      "data": {
        "$push": {
          "index": "$_id.index",
          "province": "$province",
          "count": "$count"
        }
      }
    }
  },
  {
    "$project": {
      "_id": 0
    }
  },
  {
    "$set": {
      "zero-data": [
        {
          "index": 0,
          "count": 0
        },
        {
          "index": 1,
          "count": 0
        },
        {
          "index": 2,
          "count": 0
        },
        {
          "index": 3,
          "count": 0
        }
      ]
    }
  },
  {
    "$set": {
      "data": {
        "$reduce": {
          "input": "$zero-data",
          "initialValue": [],
          "in": {
            "$let": {
              "vars": {
                "all_data": "$$value",
                "d": "$$this"
              },
              "in": {
                "$let": {
                  "vars": {
                    "found_data": {
                      "$filter": {
                        "input": "$data",
                        "cond": {
                          "$eq": [
                            "$$d.index",
                            "$$d1.index"
                          ]
                        },
                        "as": "d1"
                      }
                    }
                  },
                  "in": {
                    "$concatArrays": [
                      "$$all_data",
                      [
                        {
                          "$cond": [
                            {
                              "$eq": [
                                "$$found_data",
                                []
                              ]
                            },
                            {
                              "index": "$$d.index",
                              "count": 0
                            },
                            {
                              "$arrayElemAt": [
                                "$$found_data",
                                0
                              ]
                            }
                          ]
                        }
                      ]
                    ]
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  {
    "$project": {
      "data": {
        "$map": {
          "input": "$data",
          "in": "$$this.count"
        }
      }
    }
  }
])

推荐阅读