有没有办法在 聚合过程中获取和设置控制变量?
不,在执行聚合管道时无法跟踪上一个/下一个。
这个想法是将每个事件的事件转换为它自己的时间数组值。
您有两种选择。
击穿
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计划,但我真的很好奇,想知道如果这样的事情是可能的 –