JQL: mixpanel で複雑な分析機能を使い始める – その2 プロファイルデータ –
mixpanelのJQLでは、分析するコレクションとしてイベントデータ(Event()
)かプロファイルデータ(People()
)を選択する必要があります。
前回の記事ではイベントを扱ってみたので、今回はプロファイルデータを扱ってデータの分析をJQLで行ってみます。
やってみる
コレクションの取得
People()
関数を使って取得しますが、引数を一つ与えれます。
user_selectors:[{selector: "<<Segmentation expression>>"}]
の形式で、selectorオブジェクトで取得するユーザーレコードを制限できます。
※ Segmentation Expressionsについて
例
// [email protected]というメールアドレスのユーザー People({ user_selectors:[{ selector:'user["$email"] == "[email protected]"' }] }); // user_segmentというプロパティが定義されているユーザー People({ user_selectors:[{ selector:'defined(user["user_segment"])' }] }); // regionが千葉のユーザー People({ user_selectors:[{ selector:'user["$region"] == "Chiba"' }] });
People()で取得したユーザーは、以下のオブジェクトが返されます。
{ "distinct_id": "<<ユーザーのdistinct_id>>", "last_seen":<<Set() メソッドを介して提供される最新のユーザーレコード更新のタイムスタンプ>>, "properties": { <<ユーザーのすべてのプロパティを含むオブジェクト>> }, "time": <<最新のユーザー レコード更新のタイムスタンプ>> }
※ ユーザーセレクター式のセグメンテーション式は、ユーザープロパティにのみアクセスでき、イベントプロパティにはアクセスできません
絞り込み
user_selectors
を使わずにユーザーレコードを制限することもできます。
イベントと同じく、filter()
を使用できます。
user_selectorsの例をfilterで表すと、以下のようになります。
// [email protected]というメールアドレスのユーザー People( ).filter(function(user){ return user.properties.$email == "[email protected]" }); // user_segmentというプロパティが定義されているユーザー People( ).filter(function(user){ return user.properties.user_segment }); // regionが千葉のユーザー People( ).filter(function(user){ return user.properties.$region == "Chiba" });
イベントとの結合
イベントとプロファイルのコレクションを結合してデータを取得することも可能です。
SQLでいうjoin
で、JQLでもjoin()
関数が用意されています。
join(Events(), People())
という形でデータを取得しますが、この状態ではfull join(完全結合) となります。
3番目の引数で結合の種類とセレクターを与えることができます。
- type
- full, inner, left, right
- selectors
- 取得するイベント/ユーザーのペアを制限する {event: "event name", selector: "<
>"} オブジェクトのオプションのリスト
- 取得するイベント/ユーザーのペアを制限する {event: "event name", selector: "<
例) イベントとユーザーレコードの両方,イベントは米国から送信されたもの, ユーザーの年齢が30歳以上
{ type:"inner", selectors:[{selector: 'properties["country"] == "US" and user["age"] > 30'}] }
結合された結果は以下のオブジェクトを返します。
{ "event": { <<イベント オブジェクト。イベントのないユーザーの場合、このプロパティは未定義>> }, "user": { <<イベントに一致する distinct_id を持つユーザー オブジェクト。個別の ID がないイベントの場合、または一致するユーザー レコードがない場合、このプロパティは未定義>> }, "distinct_id": "<<イベントと一致するユーザーの両方の distinct_id>>" }
結果から分かる通り、 distinct_idをキーとして結合しているようですね。
注意点として、Join()内のコレクションに対してmap,reduce,filter,groupByの変換を適用することはできません。
join( Events({ from_date: "2022-01-01", to_date: "2022-10-01", }).filter( function(event) { return event.name == "page_open" } ), People().reduce(mixpanel.reducer.avg("properties.age")), );
はエラーとなります。
変換の関数を使う場合は、以下のように、join()
の結果に対してfilter()関数などを実行して絞り込みを行えます。
今年起こったイベントの中で、1月中にサインアップしたユーザーのログインイベントを確認する
join( Events({ from_date: "2022-01-01", to_date: "2023-01-01" }), People() ) .filter( function(tuple) { return tuple.event.name == "login" && tuple.user.properties.signup_date >= new Date("2022-01-01") && tuple.user.properties.signup_date < new Date("2022-02-01"); } )