-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* initial implementation * debug some tests and revert format to original * some minor cleanup * add screen handling * start point handling * improve indexing so multiple sessions by the same user are handled properly * all tests passing * fix type * fix types * change types * more types * rename base paths * upgrade start point functionality * assertEquals, remove inequality * Revert "assertEquals, remove inequality" This reverts commit 5eb229f. Co-authored-by: Neil Kakkar <neilkakkar@gmail.com>
- Loading branch information
1 parent
3a2a5ec
commit 06c5c6f
Showing
13 changed files
with
263 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from typing import Any, Dict, Tuple | ||
|
||
from ee.clickhouse.models.property import get_property_string_expr | ||
from ee.clickhouse.queries.event_query import ClickhouseEventQuery | ||
from posthog.constants import AUTOCAPTURE_EVENT, PAGEVIEW_EVENT, SCREEN_EVENT | ||
|
||
|
||
class PathEventQuery(ClickhouseEventQuery): | ||
def get_query(self) -> Tuple[str, Dict[str, Any]]: | ||
_fields = ( | ||
f"{self.EVENT_TABLE_ALIAS}.timestamp AS timestamp, if(event = %(screen)s, {self._get_screen_name_parsing()}, if({self.EVENT_TABLE_ALIAS}.event = %(pageview)s, {self._get_current_url_parsing()}, if({self.EVENT_TABLE_ALIAS}.event = %(autocapture)s, concat('autocapture:', {self.EVENT_TABLE_ALIAS}.elements_chain), {self.EVENT_TABLE_ALIAS}.event))) AS path_item" | ||
+ (f", {self.DISTINCT_ID_TABLE_ALIAS}.person_id as person_id" if self._should_join_distinct_ids else "") | ||
) | ||
|
||
date_query, date_params = self._get_date_filter() | ||
self.params.update(date_params) | ||
|
||
prop_filters = self._filter.properties | ||
prop_query, prop_params = self._get_props(prop_filters, allow_denormalized_props=True) | ||
self.params.update(prop_params) | ||
|
||
query = f""" | ||
SELECT {_fields} FROM events {self.EVENT_TABLE_ALIAS} | ||
{self._get_disintct_id_query()} | ||
{self._get_person_query()} | ||
WHERE team_id = %(team_id)s | ||
AND (event = %(pageview)s OR event = %(screen)s OR event = %(autocapture)s OR NOT event LIKE %(custom_event_match)s) | ||
{date_query} | ||
{prop_query} | ||
ORDER BY {self.DISTINCT_ID_TABLE_ALIAS}.person_id, {self.EVENT_TABLE_ALIAS}.timestamp | ||
""" | ||
self.params.update( | ||
{ | ||
"custom_event_match": "$%", | ||
"pageview": PAGEVIEW_EVENT, | ||
"screen": SCREEN_EVENT, | ||
"autocapture": AUTOCAPTURE_EVENT, | ||
} | ||
) | ||
return query, self.params | ||
|
||
def _determine_should_join_distinct_ids(self) -> None: | ||
self._should_join_distinct_ids = True | ||
|
||
def _get_current_url_parsing(self): | ||
path_type, _ = get_property_string_expr( | ||
"events", "$current_url", "'$current_url'", "properties", allow_denormalized_props=True | ||
) | ||
return path_type | ||
|
||
def _get_screen_name_parsing(self): | ||
path_type, _ = get_property_string_expr( | ||
"events", "$screen_name", "'$screen_name'", "properties", allow_denormalized_props=True | ||
) | ||
return path_type |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
from abc import ABC | ||
from typing import Dict, List, Tuple | ||
|
||
from ee.clickhouse.client import sync_execute | ||
from ee.clickhouse.queries.paths.path_event_query import PathEventQuery | ||
from ee.clickhouse.sql.paths.path import PATH_ARRAY_QUERY | ||
from posthog.constants import LIMIT | ||
from posthog.models import Filter, Team | ||
from posthog.models.filters.path_filter import PathFilter | ||
from posthog.queries.paths import Paths | ||
|
||
EVENT_IN_SESSION_LIMIT_DEFAULT = 5 | ||
SESSION_TIME_THRESHOLD_DEFAULT = 1800000 # milliseconds to 30 minutes | ||
|
||
|
||
class ClickhousePathsNew: | ||
_filter: PathFilter | ||
_team: Team | ||
|
||
def __init__(self, filter: PathFilter, team: Team) -> None: | ||
self._filter = filter | ||
self._team = team | ||
self.params = { | ||
"team_id": self._team.pk, | ||
"events": [], # purely a speed optimization, don't need this for filtering | ||
"event_in_session_limit": EVENT_IN_SESSION_LIMIT_DEFAULT, | ||
"session_time_threshold": SESSION_TIME_THRESHOLD_DEFAULT, | ||
"autocapture_match": "%autocapture:%", | ||
} | ||
|
||
def run(self, *args, **kwargs): | ||
|
||
results = self._exec_query() | ||
return self._format_results(results) | ||
|
||
def _format_results(self, results): | ||
if not results or len(results) == 0: | ||
return [] | ||
|
||
resp = [] | ||
for res in results: | ||
resp.append( | ||
{"source": res[0], "target": res[1], "value": res[2],} | ||
) | ||
return resp | ||
|
||
def _exec_query(self) -> List[Tuple]: | ||
query, _ = self.get_query() | ||
return sync_execute(query, self.params) | ||
|
||
def get_query(self) -> Tuple[str, dict]: | ||
path_event_query, params = PathEventQuery(filter=self._filter, team_id=self._team.pk).get_query() | ||
self.params.update(params) | ||
|
||
boundary_event_filter, start_params = self.get_start_point_filter() | ||
self.params.update(start_params) | ||
return ( | ||
PATH_ARRAY_QUERY.format(path_event_query=path_event_query, boundary_event_filter=boundary_event_filter), | ||
self.params, | ||
) | ||
|
||
def get_start_point_filter(self) -> Tuple[str, Dict]: | ||
|
||
if not self._filter.start_point: | ||
return "", {"start_point": None} | ||
|
||
return "WHERE arrayElement(limited_path, 1) = %(start_point)s", {"start_point": self._filter.start_point} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
from .filter import Filter | ||
from .path_filter import PathFilter | ||
from .retention_filter import RetentionFilter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.