Skip to content

Commit

Permalink
feat(query-engine): Add sessions timeline query (#18131)
Browse files Browse the repository at this point in the history
* Remove unused `test_journeys.py`

* Add basic sessions timeline query node

* Snapshot sessions timeline test CH queries

* Support filtering by person UUID

* Support informal sessions

* Also fetch event elements

* Fix column names being swallowed in HogQL on timezone conversion

* Include recordings in the sessions timeline

* Move the schema additions to TypeScript

* Tune timeline query

* Simplify `journeys_for` API

* Re-engineer the query to support all cases

* Revert alias preservation change

* Fix existing tests without `event_uuid` specified

* Fix some tests using `journeys_for` failing

* Make `before` and `after` optional

* Fix more tests

* Don't suggest raw HogQL functions in close matches

* Add `to_persons_query`
  • Loading branch information
Twixes authored Oct 26, 2023
1 parent 09def82 commit f7fd536
Show file tree
Hide file tree
Showing 17 changed files with 1,476 additions and 190 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def _setup_basic_test(self):
{"event": "negatively_related", "timestamp": datetime(2020, 1, 3, 14)},
{"event": "paid", "timestamp": datetime(2020, 1, 4, 14)},
]
journeys_for(events_by_person, self.team)
journeys_for(events_by_person, self.team, create_people=False)

return (
filter,
Expand Down
171 changes: 0 additions & 171 deletions ee/clickhouse/test/test_journeys.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from posthog.models.element import Element
from posthog.models.team import Team
from posthog.test.base import BaseTest, _create_event, _create_person
from posthog.test.test_journeys import journeys_for, update_or_create_person
from posthog.test.test_journeys import journeys_for


@pytest.mark.clickhouse_only
Expand Down Expand Up @@ -506,16 +506,21 @@ def test_properties_correlation_endpoint_provides_people_drill_down_urls(self):
with freeze_time("2020-01-01"):
self.client.force_login(self.user)

update_or_create_person(
_create_person(
distinct_ids=["Person 1"],
team_id=self.team.pk,
properties={"$browser": "1"},
)
update_or_create_person(
_create_person(
distinct_ids=["Person 2"],
team_id=self.team.pk,
properties={"$browser": "1"},
)
_create_person(
distinct_ids=["Person 3"],
team_id=self.team.pk,
properties={},
)

events = {
"Person 1": [
Expand All @@ -534,7 +539,7 @@ def test_properties_correlation_endpoint_provides_people_drill_down_urls(self):
],
}

journeys_for(events_by_person=events, team=self.team)
journeys_for(events_by_person=events, team=self.team, create_people=False)

odds = get_funnel_correlation_ok(
client=self.client,
Expand Down
2 changes: 1 addition & 1 deletion ee/clickhouse/views/test/test_clickhouse_trends.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ def test_insight_trends_cumulative(self):
}
],
}
created_people = journeys_for(events_by_person, self.team)
created_people = journeys_for(events_by_person, self.team, create_people=False)

# Total Volume
with freeze_time("2012-01-15T04:01:34.000Z"):
Expand Down
77 changes: 77 additions & 0 deletions frontend/src/queries/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@
{
"$ref": "#/definitions/PersonsQuery"
},
{
"$ref": "#/definitions/SessionsTimelineQuery"
},
{
"$ref": "#/definitions/HogQLQuery"
},
Expand Down Expand Up @@ -1881,6 +1884,7 @@
"HogQLQuery",
"HogQLMetadata",
"PersonsQuery",
"SessionsTimelineQuery",
"DataTableNode",
"SavedInsightNode",
"InsightVizNode",
Expand Down Expand Up @@ -2617,6 +2621,58 @@
"required": ["key", "operator", "type"],
"type": "object"
},
"SessionsTimelineQuery": {
"additionalProperties": false,
"properties": {
"after": {
"description": "Only fetch sessions that started after this timestamp (default: '-24h')",
"type": "string"
},
"before": {
"description": "Only fetch sessions that started before this timestamp (default: '+5s')",
"type": "string"
},
"kind": {
"const": "SessionsTimelineQuery",
"type": "string"
},
"personId": {
"description": "Fetch sessions only for a given person",
"type": "string"
},
"response": {
"$ref": "#/definitions/SessionsTimelineQueryResponse",
"description": "Cached query response"
}
},
"required": ["kind"],
"type": "object"
},
"SessionsTimelineQueryResponse": {
"additionalProperties": false,
"properties": {
"hasMore": {
"type": "boolean"
},
"hogql": {
"type": "string"
},
"results": {
"items": {
"$ref": "#/definitions/TimelineEntry"
},
"type": "array"
},
"timings": {
"items": {
"$ref": "#/definitions/QueryTiming"
},
"type": "array"
}
},
"required": ["results"],
"type": "object"
},
"StepOrderValue": {
"enum": ["strict", "unordered", "ordered"],
"type": "string"
Expand Down Expand Up @@ -2813,6 +2869,27 @@
"required": ["kind", "source"],
"type": "object"
},
"TimelineEntry": {
"additionalProperties": false,
"properties": {
"events": {
"items": {
"$ref": "#/definitions/EventType"
},
"type": "array"
},
"recording_duration_s": {
"description": "Duration of the recording in seconds.",
"type": "number"
},
"sessionId": {
"description": "Session ID. None means out-of-session events",
"type": "string"
}
},
"required": ["events"],
"type": "object"
},
"TrendsFilter": {
"additionalProperties": false,
"description": "`TrendsFilterType` minus everything inherited from `FilterType` and `hidden_legend_keys` replaced by `hidden_legend_indexes`",
Expand Down
28 changes: 28 additions & 0 deletions frontend/src/queries/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export enum NodeKind {
HogQLQuery = 'HogQLQuery',
HogQLMetadata = 'HogQLMetadata',
PersonsQuery = 'PersonsQuery',
SessionsTimelineQuery = 'SessionsTimelineQuery',

// Interface nodes
DataTableNode = 'DataTableNode',
Expand Down Expand Up @@ -81,6 +82,7 @@ export type AnyDataNode =
| TimeToSeeDataSessionsQuery // old API
| EventsQuery
| PersonsQuery
| SessionsTimelineQuery
| HogQLQuery
| HogQLMetadata
| WebOverviewQuery
Expand Down Expand Up @@ -544,6 +546,32 @@ export interface PersonsQuery extends DataNode {
response?: PersonsQueryResponse
}

export interface TimelineEntry {
/** Session ID. None means out-of-session events */
sessionId?: string
events: EventType[]
/** Duration of the recording in seconds. */
recording_duration_s?: number
}

export interface SessionsTimelineQueryResponse {
results: TimelineEntry[]
hasMore?: boolean
timings?: QueryTiming[]
hogql?: string
}

export interface SessionsTimelineQuery extends DataNode {
kind: NodeKind.SessionsTimelineQuery
/** Fetch sessions only for a given person */
personId?: string
/** Only fetch sessions that started after this timestamp (default: '-24h') */
after?: string
/** Only fetch sessions that started before this timestamp (default: '+5s') */
before?: string
response?: SessionsTimelineQueryResponse
}

export type WebAnalyticsPropertyFilters = (EventPropertyFilter | HogQLPropertyFilter)[]

export interface WebAnalyticsQueryBase {
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/scenes/saved-insights/SavedInsights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ export const QUERY_TYPES_METADATA: Record<NodeKind, InsightTypeMetadata> = {
icon: IconCoffee,
inMenu: true,
},
[NodeKind.SessionsTimelineQuery]: {
name: 'Sessions',
description: 'Sessions timeline query',
icon: InsightsTrendsIcon,
inMenu: true,
},
[NodeKind.HogQLQuery]: {
name: 'HogQL',
description: 'Direct HogQL query',
Expand Down
Loading

0 comments on commit f7fd536

Please sign in to comment.