0
0
mirror of https://github.com/PostHog/posthog.git synced 2024-11-30 19:41:46 +01:00
posthog/ee/clickhouse/models/cohort.py
Eric Duong 8e5347b4e1
Implement property filtering operators (#1886)
* change parsing to include operators'

* make properties test into factory

* add clickhouse test implementation and fix another test

* add custom test to clickhouse filter tests

* all tests besides json filtering

* add json test

* fix tests

* fix type errors
2020-10-19 06:01:01 -04:00

42 lines
1.9 KiB
Python

from typing import Any, Dict, Tuple
from ee.clickhouse.models.action import format_action_filter
from ee.clickhouse.models.util import get_operator
from ee.clickhouse.sql.cohort import CALCULATE_COHORT_PEOPLE_SQL, PERSON_PROPERTY_FILTER_SQL
from ee.clickhouse.sql.person import GET_DISTINCT_IDS_BY_PROPERTY_SQL
from posthog.models import Action, Cohort, Filter
def format_filter_query(cohort: Cohort) -> Tuple[str, Dict]:
filters = []
params: Dict[str, Any] = {}
for group_idx, group in enumerate(cohort.groups):
if group.get("action_id"):
action = Action.objects.get(pk=group["action_id"], team_id=cohort.team.pk)
action_filter_query, action_params = format_action_filter(action)
extract_person = "SELECT distinct_id FROM events WHERE uuid IN ({query})".format(query=action_filter_query)
params = {**params, **action_params}
filters.append("(" + extract_person + ")")
elif group.get("properties"):
filter = Filter(data=group)
for idx, prop in enumerate(filter.properties):
prepend = "{}_cohort_group_{}".format(cohort.pk, group_idx)
arg = "v{}_{}".format(prepend, idx)
operator_clause, value = get_operator(prop, arg)
prop_filters = "(ep.key = %(k{prepend}_{idx})s) AND {operator_clause}".format(
idx=idx, operator_clause=operator_clause, prepend=prepend
)
clause = GET_DISTINCT_IDS_BY_PROPERTY_SQL.format(filters=prop_filters)
filters.append("(" + clause + ")")
params.update({"k{}_{}".format(prepend, idx): prop.key, arg: value})
separator = " OR distinct_id IN "
joined_filter = separator.join(filters)
person_id_query = CALCULATE_COHORT_PEOPLE_SQL.format(query=joined_filter)
return person_id_query, params