在 mongo 聚合中按无顺序的字符串数组的内容分组

Group by the content of array of string with out order in mongo aggregation

我在 MongoDB(猫鼬)中的聚合框架有问题,这就是问题所在。我有以下数据库 scheme.so 我想做的是计算只能通过 MobileCard 或两者访问的人数。没有任何订单,

  {
       '_id': ObjectId,
       'user_access_type': ['Mobile' , 'Card']
   }
    {
       '_id': ObjectId,
       'user_access_type': ['Card' , 'Mobile']
   }
    {
       '_id': ObjectId,
       'user_access_type': ['Mobile']
   }
  {
       '_id': ObjectId,
       'user_access_type': ['Card']
   }

现在我正在使用它,但它只按 user_access_type 数组的顺序分组,

[ { "$group" : {   "_id": {"User" : "$user_access_type"} ,   "count": {"$sum" : 1}   }]   

这是输出:

{
            "_id": {
                "User": [
                    "Card",
                    "Mobile"
                ]
            },
            "count": 1
        },
        {
            "_id": {
                "_id": "5f7dce2359aaf004985f98eb",
                "User": [
                    "Mobile",
                    "Card"
                ]
            },
            "count": 1
        },
        {
            "_id": {
                "User": [
                    "Mobile"
                ]
            },
            "count": 1
        },
        
        {
            "_id": {
                "User": [
                    "Card"
                ]
            },
            "count": 1
        },

对比我想要的:

  {
            "_id": {
                "User": [
                    "Card",
                    "Mobile"     // we can say both
                ]
            },
            "count": 2     // does not depend on order
        },
        {
            "_id": {
                "User": [
                    "Mobile"
                ]
            },
            "count": 1
        },
        {
            "_id": {
                "User": [
                    "Card"
                ]
            },
            "count": 1
        },

您也可以使用其他选项 $function,

  • $function可以允许添加javascript代码,可以使用sort()对数组进行排序
db.collection.aggregate([
  {
    $addFields: {
      user_access_type: {
        $function: {
          body: function(user_access_type){
              return user_access_type.sort();
          },
          args: ["$user_access_type"],
          lang: "js"
        }
      }
    }
  },
  {
    $group: {
      _id: "$user_access_type",
      count: { $sum: 1 }
    }
  }
])

第二个选项,

如果 user_access_type 数组始终具有唯一元素,那么您可以在 user_access_type 数组上使用 $setUnion 运算符作为自联合,这将如何以相同的顺序重新排序数组,

db.collection.aggregate([
  {
    $addFields: {
      user_access_type: {
        $setUnion: "$user_access_type"
      }
    }
  },
  {
    $group: {
      _id: "$user_access_type",
      count: { $sum: 1 }
    }
  }
])

Playground