我有一個集合,其中包含有關事件和與會者的資訊。集合中的檔案看起來像這樣
{event: event_1, attendees: [A, B, C]} //A、B和C參加了event_1。
{event: event_2, attendees: [A, B]} //A和B參加了event_2。
{event: event_3, attendees: [A]} //A只參加了event_3。
我想建立的是一個查詢,讓我知道每個與會者參加了多少次活動,以及他與其他與會者見面的次數。換句話說,我想獲得類似這樣的資訊
{attendee: A, howManyEvents: 3, togetherWith: B, howManyTimes: 2}。
{attendee: A, howManyEvents: 3, togetherWith: C, howManyTimes: 1}。
{attendee: B, howManyEvents: 2, togetherWith: A, howManyTimes: 2}。
{attendee: B, howManyEvents: 2, togetherWith: C, howManyTimes: 1}。
{attendee: C, howManyEvents: 1, togetherWith: A, howManyTimes: 1}。
{attendee: C, howManyEvents: 1, togetherWith: B, howManyTimes: 1}。
這樣的串列將允許我知道,例如,查詢{attendee: B, togetherWith: A},任何時候B去參加一個活動都會遇到A(howManyEvents和howManyTimes都是2)。同樣地,1/3的A去參加一個活動的時候也會遇到C。
是否有辦法建立一個查詢來回傳這樣的一個串列?
uj5u.com熱心網友回復:
我不認為有任何直接的方法可以做到這一點,但你可以嘗試下面的聚合管道,
我不認為有任何直接的方法可以做到這一點。
$addFields添加attendees欄位的副本 。
$unwind解構attendees陣列 。
$filter對togetherWith進行迭代回圈,并從復制欄位中洗掉當前attendee。
$unwind解構togetherWith陣列 。
$group通過attendee構建togetherWith陣列,并計算howManyEvents。
$unwind解構togetherWith陣列 。
$group通過attendee和togetherWith得到howManyTimes的計數。
$project來格式化結果 。
db.collection.aggregate( [
{ $addFields: { togetherWith: "$attendees" }. },
{ $unwind: "$attendees" },
{
$addFields: {
togetherWith: {
$filter: {
input: "$togetherWith"/span>,
cond: { $ne: ["$this"/span>, "$attendees"/span>] }
}
}
}
},
{ $unwind: "$togetherWith"/span> },
{
$group: {
_id: "$attendees"/span>,
togetherWith: { $push: "$togetherWith"/span> },
howManyEvents: { $sum: 1 }
}
},
{ $unwind: "$togetherWith"/span> },
{
$group: {
_id: {
attendee: "$_id",
togetherWith: "$togetherWith".
},
howManyEvents: { $first: "$howManyEvents" }。
howManyTimes: { $sum: 1 }
}
},
{
$project: {
_id: 0,
attendee: "$_id.attendee",
togetherWith: "$_id.togetherWith"。
howManyEvents: 1,
howManyTimes: 1.
}
}
])
uj5u.com熱心網友回復:
查詢產生你想要的結果。
為了理解它,可以幫助我們逐個階段地去看輸出。
查詢
查詢
*如果你看到together與NULL,它是針對1個成員的活動,它的重要資訊是如果一個人只參加了1個活動,而且是單獨參加的
db.collection.aggregate( [
{
"$set"/span>: {
"a"/span>: {
"$map": {
"input": "$attendees",
"in": {
"attendee": "$a",
"event": "$event",
"togetherWith": {
"$setDifference": [
"$attendees",
[
"$a": "$a""as": "a"。
}
}
}
},
{
"$project": {
"_id": 0,
"a": 1.
}
},
{
"$unwind": {
"path": "$a": "path".
}
},
{
"$replaceRoot": {
"newRoot": "$a": "newRoot".
}
},
{
"$unwind": {
"path": "$togetherWith",
"reserveNullAndEmptyArrays": true。
}
},
{
"$set": {
"togetherWith": {
"$ifNull": [
"$togetherWith",
null.
]
}
}
},
{
"$group": {
"_id": "$attendee",
"howManyEvents": {
"$addToSet": "$event": "$event".
},
"together": {
"$push": {
"togetherWith": "$togetherWith",
"howManyTimes": 1.
}
}
}
},
{
"$set": {
"attendee": "$_id": "出席者".
}
},
{
"$project": {
"_id": 0.
}
},
{
"$set": {
"howManyEvents": {
"$size": "$howManyEvents": "$size".
}
}
},
{
"$unwind": {
"path": "$together".
}
},
{
"$replaceRoot": {
"newRoot"/span>: {
"$mergeObjects": [
"$together",
"$ROOT".
]
}
}
},
{
"$project": {
"together": 0.
}
},
{
"$group": {
"_id": {
"attendee": "$attendee",
"togetherWith": "$togetherWith".
},
"howManyEvents": {
"$first": "$howManyEvents": "$first".
},
"howManyTimes": {
"$sum": "$howManyTimes": "$sum".
}
}
},
{
"$replaceRoot"/span>: {
"newRoot"/span>: {
"$mergeObjects": [
"$_id",
"$ROOT".
]
}
}
},
{
"$project": {
"_id": 0.
}
}
])
Query2(替代解決方案面和更多的陣列操作)
{:togetherWith ".." :howManyTimes 1}
{
"attendee"。"A"。
"togetherWith": "B",
"howManyTimes": 1,
"event": "event_1"。
},
{
"attendee": "A",
"togetherWith": "C",
"howManyTimes": 1,
"event": "event_1".
}
...
- 計算不同的事件(多少個事件)
- 求和多少次(多少次) 。
*如果你看到結果,它們還包含"howManyTimes": 0成員,這發生在事件只有一個成員的時候,對A來說沒有用,因為我們有來自其他檔案的howManyEvents。
但是對于 "Z "來說是有用的,所以我保留了這些
db.collection.aggregate( [
{
"$set"/span>: {
"a"/span>: {
"$map": {
"input": "$attendees",
"in": {
"attendee": "$a",
"event": "$event",
"togetherWith": {
"$filter": {
"input": {
"$map": {
"input": "$attendees",
"in": {
"$cond": [
{
"$ne": [
"$a",
"$a1".
]
},
{
"togetherWith": "$a1",
"howManyTimes": 1。
},
null: 1 },.
]
},
"as": "a1": "a1".
}
},
"cond": {
"$ne": [
"$f",
null"as": "f": "f".
}
}
},
"as": "a": "a".
}
}
}
},
{
"$project": {
"_id": 0,
"a": 1.
}
},
{
"$unwind": {
"path": "$a": "path".
}
},
{
"$unwind": {
"path": "$a.togetherWith",
"reserveNullAndEmptyArrays": true。
}
},
{
"$project": {
"attendee": "$a.attendee",
"togetherWith": "$a.togetherWith.togetherWith"。
"howManyTimes": "$a.togetherWith.howManyTimes",
"event": "$a.event".
}
},
{
"$facet": {
"a": [
{
"$group": {
"_id": "$attendee",
"howManyEvents": {
"$addToSet": "$event": "$event".
}
}
},
{
"$set": {
"attendee": "$_id": "出席者".
}
},
{
"$project": {
"_id": 0.
}
},
{
"$set": {
"howManyEvents": {
"$size": "$howManyEvents": "$size".
}
}
}
],
"b"/span>: [
{
"$group": {
"_id": {
"attendee": "$attendee",
"togetherWith": "$togetherWith".
},
"howManyTimes": {
"$sum": "$howManyTimes": "$sum".
}
}
},
{
"$replaceRoot"/span>: {
"newRoot"/span>: {
"$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" "$m1"
}
},
0
]
}
},
"in": {
"$mergeObjects": [
"$m",
{
"howManyEvents": "$$howManyEvents.howManyEvents".
}
]
}
}
},
"as": "m"。
}
}
}
},
{
"$unwind": {
"path": "$b": "path".
}
},
{
"$replaceRoot": {
"newRoot": "$b": "newRoot".
}
}
])
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/332488.html
標籤:
上一篇:如何用模板字面型別專案生成陣列
