有沒有辦法在 聚合過程中獲取和設置控制變量?
不,在執行聚合管道時無法跟蹤上一個/下一個。
這個想法是將每個事件的事件轉換爲它自己的時間數組值。
您有兩種選擇。
擊穿
Video Play : [1,5,7]
Video Pause : [3,6,10]
Features : [2,4,8,9]
Play-Features : 2 8,9
Video play-pause pair : [1,3],[5,6],[7,10]
Pause-Features : 4
Video pause-play pair : [3,5],[6,7],[10,-]
期望輸出
{count:3}
第一個選項:(你做聚合管道全部工作)
使用額外階段的文檔轉換爲事件陣列結構。
考慮下面的文件
db.collection.insertMany([
{eventName:"Video Play",creation:1},
{eventName:"Click Features 1",creation:2},
{eventName:"Video Pause",creation:3},
{eventName:"Click Features 1",creation:4},
{eventName:"Video Play",creation:5},
{eventName:"Video Pause",creation:6},
{eventName:"Video Play",creation:7},
{eventName:"Click Features 1",creation:8},
{eventName:"Click Features 1",creation:9},
{eventName:"Video Pause",creation:10}
]);
您可以使用下面聚集
下聚合使用兩個$group
階段的事件轉換成其時間序列,然後$project
階段項目($let
)每個事件創作數組變成一個變量。
對於內部$let
邏輯的解釋看選項2
db.collection.aggregate([
{
"$sort": {
"eventName": 1,
"creation": 1
}
},
{
"$group": {
"_id": "$eventName",
"creations": {
"$push": "$creation"
}
}
},
{
"$group": {
"_id": "null",
"events": {
"$push": {
"eventName": "$_id",
"creations": "$creations"
}
}
}
},
{
"$project": {
"count": {
"$let": {
"vars": {
"video_play_events": {
"$arrayElemAt": [
"$events.creations",
{
"$indexOfArray": [
"$events.eventName",
"Video Play"
]
}
]
},
"click_features_event": {
"$arrayElemAt": [
"$events.creations",
{
"$indexOfArray": [
"$events.eventName",
"Click Features 1"
]
}
]
},
"video_pause_events": {
"$arrayElemAt": [
"$events.creations",
{
"$indexOfArray": [
"$events.eventName",
"Video Pause"
]
}
]
}
},
"in": {*}
}
}
}
}
])
*你有事件創作陣列在這一點上每一個事件。在彙總代碼下面插入,並用$$video_play_events
替換$video_play_events
等,以訪問$let
階段的變量。
第二個選項:(您保存在自己的數組事件)
db.collection.insert([
{
"video_play_events": [
1,
5,
7
],
"click_features_event": [
2,
4,
8,
9
],
"video_pause_events": [
3,
6,
10
]
}
])
您可以通過添加額外的字段「計數」來限制管理陣列生長的任何事件,你可以在一個文檔中存儲。
對於選定的時間片,您可以有多個文檔。
這將簡化到下面的聚合。
以下聚合迭代超過video_play_events
並過濾每個播放和暫停對的所有點擊功能(pl
和pu
)。
$size
計算每個播放和暫停對之間的特徵元素的數目,然後是$map
+ $sum
以計算所有播放暫停對的所有特徵事件。
db.collection.aggregate([
{
"$project": {
"count": {
"$sum": {
"$map": {
"input": {
"$range": [
0,
{
"$subtract": [
{
"$size": "$video_play_events"
},
1
]
}
]
},
"as": "z",
"in": {
"$let": {
"vars": {
"pl": {
"$arrayElemAt": [
"$video_pause_events",
"$$z"
]
},
"pu": {
"$arrayElemAt": [
"$video_play_events",
{
"$add": [
1,
"$$z"
]
}
]
}
},
"in": {
"$size": {
"$filter": {
"input": "$click_features_event",
"as": "fe",
"cond": {
"$and": [
{
"$gt": [
"$$fe",
"$$pl"
]
},
{
"$lt": [
"$$fe",
"$$pu"
]
}
]
}
}
}
}
}
}
}
}
}
}
}
])
注:
你打運行基於沒有你想在這兩種情況下聚集文件16 MB的文件限制的風險。
您可以使用異步模塊運行具有適當過濾器的並行查詢,以包含要聚合的數據,然後由客戶端邏輯對所有部分進行計數。
更好地流,做在應用端 – sidgate
我認爲這是棘手的做,在我的情況,我有一個B計劃,但我真的很好奇,想知道如果這樣的事情是可能的 –