アグリゲーションプロセス中に制御変数を取得して設定する方法はありますか?
いいえ、アグリゲーションパイプラインが実行されたときの前後を追跡する方法はありません。
考えられるのは、各イベントのイベントを独自のタイムアレイ値に変換することです。
2つのオプションがあります。
内訳
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}
]);
の下に考えてみましょう
凝集は、以下のプロジェクトに$project
段階($let
)各イベントの創造に続いてその時間配列にイベントを変換するために2つの$group
のステージを使用しています配列を変数に変換します。あなたはこの時点では、各イベントのイベント創作配列を持つ* $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
]
}
])
あなたは一つの文書に格納できるイベントの一切を制限するために余分なフィールド「count」を追加することにより、配列の成長を管理することはできません。
選択したタイムスライスに複数のドキュメントを含めることができます。
これにより、以下の集約が簡素化されます。
以下の集計は、video_play_events
を繰り返し、各再生と一時停止のペア(pl
とpu
)のすべてのクリック機能をフィルタリングします。全てのプレイポーズペアのすべての機能のイベントをカウントする$map
+ $sum
続く各プレイとポーズ対の間の機能要素のnoをカウントする
$size
。
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メガバイトの文書の上限を打つのリスクを実行します。
非同期モジュールを使用すると、適切なフィルタを使用して並列クエリを実行して、集計するデータを格納し、その後にすべてのパーツを数えるクライアント側のロジックを含めることができます。
アプリケーションの側でより良いストリームとする – sidgate
私のケースでは、これを行うのは難しいと思いますが、私はプランBを持っていますが、この種のことが可能かどうかを知りたいのは本当に興味があります –