feature(chalice): search sessions by x/y coordinates
feature(chalice): search heatmaps by x/y coordinates
This commit is contained in:
parent
f1e1d37d8e
commit
5b6e9ab7e0
4 changed files with 63 additions and 5 deletions
|
|
@ -61,6 +61,9 @@ def get_heat_map_chart(project: schemas.ProjectContext, user_id, data: schemas.C
|
||||||
return None
|
return None
|
||||||
data.series[0].filter.filters += data.series[0].filter.events
|
data.series[0].filter.filters += data.series[0].filter.events
|
||||||
data.series[0].filter.events = []
|
data.series[0].filter.events = []
|
||||||
|
print(">>>>>>>>>>>>>>>>>>>>>>>>><")
|
||||||
|
print(data.series[0].filter.model_dump())
|
||||||
|
print(">>>>>>>>>>>>>>>>>>>>>>>>><")
|
||||||
return heatmaps.search_short_session(project_id=project.project_id, user_id=user_id,
|
return heatmaps.search_short_session(project_id=project.project_id, user_id=user_id,
|
||||||
data=schemas.HeatMapSessionsSearch(
|
data=schemas.HeatMapSessionsSearch(
|
||||||
**data.series[0].filter.model_dump()),
|
**data.series[0].filter.model_dump()),
|
||||||
|
|
|
||||||
|
|
@ -1293,9 +1293,6 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu
|
||||||
events_conditions.append({"type": event_where[-1]})
|
events_conditions.append({"type": event_where[-1]})
|
||||||
|
|
||||||
if is_not:
|
if is_not:
|
||||||
# event_where.append(json_condition(
|
|
||||||
# "sub", "$properties", _column, op, event.value, e_k
|
|
||||||
# ))
|
|
||||||
event_where.append(
|
event_where.append(
|
||||||
sh.multi_conditions(
|
sh.multi_conditions(
|
||||||
get_sub_condition(col_name=f"sub.`$properties`.{_column}",
|
get_sub_condition(col_name=f"sub.`$properties`.{_column}",
|
||||||
|
|
@ -1317,7 +1314,33 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu
|
||||||
event.value, value_key=e_k)
|
event.value, value_key=e_k)
|
||||||
)
|
)
|
||||||
events_conditions[-1]["condition"] = event_where[-1]
|
events_conditions[-1]["condition"] = event_where[-1]
|
||||||
|
elif event_type == schemas.EventType.CLICK_COORDINATES:
|
||||||
|
event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main "
|
||||||
|
event_where.append(
|
||||||
|
f"main.`$event_name`='{exp_ch_helper.get_event_type(schemas.EventType.CLICK, platform=platform)}'")
|
||||||
|
events_conditions.append({"type": event_where[-1]})
|
||||||
|
|
||||||
|
if is_not:
|
||||||
|
event_where.append(
|
||||||
|
sh.coordinate_conditions(
|
||||||
|
condition_x=f"sub.`$properties`.normalized_x",
|
||||||
|
condition_y=f"sub.`$properties`.normalized_y",
|
||||||
|
values=event.value, value_key=e_k, is_not=True)
|
||||||
|
)
|
||||||
|
events_conditions_not.append(
|
||||||
|
{
|
||||||
|
"type": f"sub.`$event_name`='{exp_ch_helper.get_event_type(schemas.EventType.CLICK, platform=platform)}'"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
events_conditions_not[-1]["condition"] = event_where[-1]
|
||||||
|
else:
|
||||||
|
event_where.append(
|
||||||
|
sh.coordinate_conditions(
|
||||||
|
condition_x=f"main.`$properties`.normalized_x",
|
||||||
|
condition_y=f"main.`$properties`.normalized_y",
|
||||||
|
values=event.value, value_key=e_k, is_not=True)
|
||||||
|
)
|
||||||
|
events_conditions[-1]["condition"] = event_where[-1]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ def reverse_sql_operator(op):
|
||||||
return "=" if op == "!=" else "!=" if op == "=" else "ILIKE" if op == "NOT ILIKE" else "NOT ILIKE"
|
return "=" if op == "!=" else "!=" if op == "=" else "ILIKE" if op == "NOT ILIKE" else "NOT ILIKE"
|
||||||
|
|
||||||
|
|
||||||
def multi_conditions(condition, values, value_key="value", is_not=False):
|
def multi_conditions(condition, values, value_key="value", is_not=False) -> str:
|
||||||
query = []
|
query = []
|
||||||
for i in range(len(values)):
|
for i in range(len(values)):
|
||||||
k = f"{value_key}_{i}"
|
k = f"{value_key}_{i}"
|
||||||
|
|
@ -79,3 +79,30 @@ def single_value(values):
|
||||||
if isinstance(v, Enum):
|
if isinstance(v, Enum):
|
||||||
values[i] = v.value
|
values[i] = v.value
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
def coordinate_conditions(condition_x, condition_y, values, value_key="value", is_not=False):
|
||||||
|
query = []
|
||||||
|
if len(values) == 2:
|
||||||
|
# if 2 values are provided, it means x=v[0] and y=v[1]
|
||||||
|
for i in range(len(values)):
|
||||||
|
k = f"{value_key}_{i}"
|
||||||
|
if i == 0:
|
||||||
|
query.append(f"{condition_x}=%({k})s")
|
||||||
|
elif i == 1:
|
||||||
|
query.append(f"{condition_y}=%({k})s")
|
||||||
|
|
||||||
|
elif len(values) == 4:
|
||||||
|
# if 4 values are provided, it means v[0]<=x<=v[1] and v[2]<=y<=v[3]
|
||||||
|
for i in range(len(values)):
|
||||||
|
k = f"{value_key}_{i}"
|
||||||
|
if i == 0:
|
||||||
|
query.append(f"{condition_x}>=%({k})s")
|
||||||
|
elif i == 1:
|
||||||
|
query.append(f"{condition_x}<=%({k})s")
|
||||||
|
elif i == 2:
|
||||||
|
query.append(f"{condition_y}>=%({k})s")
|
||||||
|
elif i == 3:
|
||||||
|
query.append(f"{condition_y}<=%({k})s")
|
||||||
|
|
||||||
|
return "(" + (" AND " if is_not else " OR ").join(query) + ")"
|
||||||
|
|
|
||||||
|
|
@ -407,6 +407,7 @@ class EventType(str, Enum):
|
||||||
SWIPE_MOBILE = "swipeMobile"
|
SWIPE_MOBILE = "swipeMobile"
|
||||||
EVENT = "event"
|
EVENT = "event"
|
||||||
INCIDENT = "incident"
|
INCIDENT = "incident"
|
||||||
|
CLICK_COORDINATES = "clickCoordinates"
|
||||||
|
|
||||||
|
|
||||||
class PerformanceEventType(str, Enum):
|
class PerformanceEventType(str, Enum):
|
||||||
|
|
@ -660,6 +661,10 @@ class SessionSearchEventSchema(BaseModel):
|
||||||
elif self.type == EventType.GRAPHQL:
|
elif self.type == EventType.GRAPHQL:
|
||||||
assert isinstance(self.filters, List) and len(self.filters) > 0, \
|
assert isinstance(self.filters, List) and len(self.filters) > 0, \
|
||||||
f"filters should be defined for {EventType.GRAPHQL}"
|
f"filters should be defined for {EventType.GRAPHQL}"
|
||||||
|
elif self.type == EventType.CLICK_COORDINATES:
|
||||||
|
assert isinstance(self.value, List) \
|
||||||
|
and (len(self.value) == 0 or len(self.value) == 2 or len(self.value) == 4), \
|
||||||
|
f"value should be [x,y] or [x1,x2,y1,y2] for {EventType.CLICK_COORDINATES}"
|
||||||
|
|
||||||
if isinstance(self.operator, ClickEventExtraOperator):
|
if isinstance(self.operator, ClickEventExtraOperator):
|
||||||
assert self.type == EventType.CLICK, \
|
assert self.type == EventType.CLICK, \
|
||||||
|
|
@ -1521,7 +1526,7 @@ class MetricSearchSchema(_PaginatedSchema):
|
||||||
|
|
||||||
|
|
||||||
class _HeatMapSearchEventRaw(SessionSearchEventSchema):
|
class _HeatMapSearchEventRaw(SessionSearchEventSchema):
|
||||||
type: Literal[EventType.LOCATION] = Field(...)
|
type: Literal[EventType.LOCATION, EventType.CLICK_COORDINATES] = Field(...)
|
||||||
|
|
||||||
|
|
||||||
class HeatMapSessionsSearch(SessionsSearchPayloadSchema):
|
class HeatMapSessionsSearch(SessionsSearchPayloadSchema):
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue