查询产生您想要的结果。
要理解它,它可以帮助逐步进行并查看输出。
查询
- 映射添加with字段,每次缺少1个成员(当前成员)
- 放松
- 按参与者分组以总结不同的事件 => howManyTimes
- 放松
- 按参加者分组,然后 sum togetherWith : 1 => togetherWith(总数)
*如果您与 NULL 一起看到它的 1 个成员的活动,它的重要信息是如果一个人只参加了 1 个活动并且是单独的
Test code here
db.collection.aggregate([
{
"$set": {
"a": {
"$map": {
"input": "$attendees",
"in": {
"attendee": "$$a",
"event": "$event",
"togetherWith": {
"$setDifference": [
"$attendees",
[
"$$a"
]
]
}
},
"as": "a"
}
}
}
},
{
"$project": {
"_id": 0,
"a": 1
}
},
{
"$unwind": {
"path": "$a"
}
},
{
"$replaceRoot": {
"newRoot": "$a"
}
},
{
"$unwind": {
"path": "$togetherWith",
"preserveNullAndEmptyArrays": true
}
},
{
"$set": {
"togetherWith": {
"$ifNull": [
"$togetherWith",
null
]
}
}
},
{
"$group": {
"_id": "$attendee",
"howManyEvents": {
"$addToSet": "$event"
},
"together": {
"$push": {
"togetherWith": "$togetherWith",
"howManyTimes": 1
}
}
}
},
{
"$set": {
"attendee": "$_id"
}
},
{
"$project": {
"_id": 0
}
},
{
"$set": {
"howManyEvents": {
"$size": "$howManyEvents"
}
}
},
{
"$unwind": {
"path": "$together"
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$together",
"$$ROOT"
]
}
}
},
{
"$project": {
"together": 0
}
},
{
"$group": {
"_id": {
"attendee": "$attendee",
"togetherWith": "$togetherWith"
},
"howManyEvents": {
"$first": "$howManyEvents"
},
"howManyTimes": {
"$sum": "$howManyTimes"
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$_id",
"$$ROOT"
]
}
}
},
{
"$project": {
"_id": 0
}
}
])
Query2(替代解决方案方面和更多数组操作)
- 第一张地图是添加
{:togetherWith ".." :howManyTimes 1}
致每一位关注者
- 2 展开以获得类似的结果
{
"attendee": "A",
"togetherWith": "B",
"howManyTimes": 1,
"event": "event_1"
},
{
"attendee": "A",
"togetherWith": "C",
"howManyTimes": 1,
"event": "event_1"
}
...
- 2 个组在一个方面
- 统计不同的事件(有多少事件)
- 求和多少次(多少次)
- 然后它是一个结合了这两个数组的信息的地图
- 包含所有信息的该数组的 1 次展开
- 简单的转换
*如果您看到结果还包含 "howManyTimes": 0 成员,这发生在事件只有 1 个成员时,因为 A 没有用,因为我们有来自其他文档的 howManyEvents,
但是对于“Z”来说它很有用,所以我保留了那些
Test code here
db.collection.aggregate([
{
"$set": {
"a": {
"$map": {
"input": "$attendees",
"in": {
"attendee": "$$a",
"event": "$event",
"togetherWith": {
"$filter": {
"input": {
"$map": {
"input": "$attendees",
"in": {
"$cond": [
{
"$ne": [
"$$a",
"$$a1"
]
},
{
"togetherWith": "$$a1",
"howManyTimes": 1
},
null
]
},
"as": "a1"
}
},
"cond": {
"$ne": [
"$$f",
null
]
},
"as": "f"
}
}
},
"as": "a"
}
}
}
},
{
"$project": {
"_id": 0,
"a": 1
}
},
{
"$unwind": {
"path": "$a"
}
},
{
"$unwind": {
"path": "$a.togetherWith",
"preserveNullAndEmptyArrays": true
}
},
{
"$project": {
"attendee": "$a.attendee",
"togetherWith": "$a.togetherWith.togetherWith",
"howManyTimes": "$a.togetherWith.howManyTimes",
"event": "$a.event"
}
},
{
"$facet": {
"a": [
{
"$group": {
"_id": "$attendee",
"howManyEvents": {
"$addToSet": "$event"
}
}
},
{
"$set": {
"attendee": "$_id"
}
},
{
"$project": {
"_id": 0
}
},
{
"$set": {
"howManyEvents": {
"$size": "$howManyEvents"
}
}
}
],
"b": [
{
"$group": {
"_id": {
"attendee": "$attendee",
"togetherWith": "$togetherWith"
},
"howManyTimes": {
"$sum": "$howManyTimes"
}
}
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$_id",
"$$ROOT"
]
}
}
},
{
"$project": {
"_id": 0
}
}
]
}
},
{
"$set": {
"b": {
"$map": {
"input": "$b",
"in": {
"$let": {
"vars": {
"howManyEvents": {
"$arrayElemAt": [
{
"$filter": {
"input": "$a",
"cond": {
"$eq": [
"$$m.attendee",
"$$m1.attendee"
]
},
"as": "m1"
}
},
0
]
}
},
"in": {
"$mergeObjects": [
"$$m",
{
"howManyEvents": "$$howManyEvents.howManyEvents"
}
]
}
}
},
"as": "m"
}
}
}
},
{
"$unwind": {
"path": "$b"
}
},
{
"$replaceRoot": {
"newRoot": "$b"
}
}
])