执行 $group 并计数 mongoDB 聚合

Perform $group and count in mongoDB aggregation

鉴于我有一个复杂的分组要求,我想知道实现我想要的结果的最佳方法是什么。 我的数据($project 阶段的结果)看起来像这样:

{
_id:$id
status:"available"
inspectionStatus:"done"
state:"completed"
category:"One"
},
{
_id:$id
status:"booked"
inspectionStatus:"none"
state:"active"
category:"Two"
},
.
.
.

我尝试使用 $facet 创建多个存储桶,因为我尝试创建的分组是 $status + $state + $inspection 的聚合,但是执行时间是无法接受的,大约需要 1639763842 毫秒。 我不能使用 use $accumulator 因为 mongoDB 版本(虽然我们总是可以升级到 4.4.x)但是我不确定使用 $accumulator 是否会产生更好的效果响应时间。

$facet阶段包括:

{
  "available": [
    {"$match": 
      {$and: [
        {"status": "available"},
        {"inspectionStatus": "done"}
      ]}
    }
  ],
  "matched": [
    {"$match": 
      {$and: [
        {"status": "booked"},
        {"state": "booked"}
        ]
      }
    }
  ],
  "inIntake": [ 
    {"$match": 
      {$and: [
        {"status": "available"},
        {"inspectionStatus": {$ne: "done"}}
        ]
      }
    }
  ],
  "active": [
    {"$match": 
      {$and: [
        {"status": "booked"},
        {"state": "active"}
        ]
      }
    }
  ],
  "unreturned":[
    {"$match": 
      {"status": "forceCompleted"}
    }
  ]
}

如果您真的想将逻辑推送到数据库,这里有一个解决方案——但您仍然需要按文档检查 XX 字段文档:

db.foo.aggregate([
    {$addFields: {XX: {$switch: {
    branches: [
            { case: {
        $and: [{$eq:["$status","available"]},{$eq:["$inspectionStatus","done"]}]
            }, then:'AVAILABLE' },
            { case: {
        $and: [{$eq:["$status","booked"]},{$eq:["$state","booked"]}]
            }, then:'MATCHED' },
            { case: {
        $and: [{$eq:["$status","available"]},{$ne:["$inspectionStatus","done"]}]
            }, then:'IN_INTAKE' },
            { case: {
        $and: [{$eq:["$status","booked"]},{$eq:["$state","active"]}]
            }, then:'ACTIVE' },
            { case: {
        $eq:["$status","forceCompleted"]
            }, then:'UNRETURNED' },
    ],
        default: null
    }}
                 }}
    ,{$match: {XX: {$ne: null}}}
]);

这方面的端到端计时实际上比简单的 find() 好几毫秒,因为传输的 material 较少,但当然数据库引擎正在更努力地处理管道。