我正试图从两个地方统计MongoDB集合中的状态出现次数。给定下面这样的文档,如果在一个聚合中statuses
下没有雕像,我想从文档的根计算status
,但无法确定如何有条件地执行此操作。
{
"id": "some unique id",
"groupId": "some many to one id mapping",
...
"status": "ACCEPTED",
"statuses": [{
"personId": "some id",
"status": "ACCEPTED"
}, {
"personId": "some other person",
"status": "REMOVED"
}]
}
现在我有一个聚合来计算所有statuses.status
,但如果没有雕像,就无法获得准确的计数。这可能需要更改模型,但理想情况下,我认为有一种方法可以有条件地做到这一点。
我的聚合管道如下所示:
final List<DBObject> statusPipeline = Aggregation.newAggregation(
match,
Aggregation.group("groupId", "statuses.personId", "statuses.status"),
Aggregation.unwind("status"),
Aggregation.group("$groupId", "status").count().as("total")
)
.toPipeline(Aggregation.DEFAULT_CONTEXT).stream()
.map(BasicDBObject::new)
.collect(Collectors.toList());
我想包含在聚合中的文档示例:
{
"id": "some unique id",
"groupId": "some many to one id mapping",
...
"status": "UNPROVISIONED",
"statuses": []
}
这两份文件的最终计数应为"未提供:1"、"已接受:1"one_answers"已删除:1"。或者类似于:
[{
"groupId": "A",
"UNPROVISIONED": 1
}, {
"groupId": "A",
"ACCEPTED": 1
}, {
"groupId": "A",
"REMOVED": 1,
}]
我不确定我是否完全理解分组/计数逻辑,但也许这提供了您想要的输出。
db.collection.aggregate([
{
"$set": {
"statuses": {
"$cond": [
{ // if there are statuses.status ...
"$gt": [{"$size": "$statuses.status"}, 0]
},
// ... use those
"$statuses.status",
// ... otherwise use status
["$status"]
]
}
}
},
{
"$unwind": "$statuses"
},
{
"$group": {
"_id": {
"groupId": "$groupId",
"status": "$statuses"
},
"count": {"$count": {}}
}
}
])
在mongoplayground.net上试试。