Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hogql): add funnel correlation actor queries #20726

Merged
merged 43 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
79cc530
add funnel correlation actors query
thmsobrmlr Mar 6, 2024
38ab4e0
scaffold
thmsobrmlr Mar 6, 2024
1b6b9bb
query nodes
thmsobrmlr Mar 6, 2024
29350fd
add tests
thmsobrmlr Mar 6, 2024
ed1fefe
more tests
thmsobrmlr Mar 6, 2024
256eeb8
more tests
thmsobrmlr Mar 6, 2024
74d6c4a
more tests and properties query
thmsobrmlr Mar 6, 2024
dd447ff
Update query snapshots
github-actions[bot] Mar 6, 2024
5304d10
Update UI snapshots for `webkit` (2)
github-actions[bot] Mar 6, 2024
1414a59
correlation tests
thmsobrmlr Mar 6, 2024
e5fae56
Update UI snapshots for `webkit` (2)
github-actions[bot] Mar 6, 2024
a0de270
fix test
thmsobrmlr Mar 6, 2024
7a7d963
snapshot update
thmsobrmlr Mar 6, 2024
da325c3
formatting
thmsobrmlr Mar 6, 2024
8c0027a
fix types
thmsobrmlr Mar 6, 2024
39fedec
fix test_funnel_correlation_with_event_properties
thmsobrmlr Mar 7, 2024
a9ea2c1
add test_funnel_correlation_with_event_properties_exclusions
thmsobrmlr Mar 7, 2024
688e7da
fix test_basic_funnel_correlation_with_properties and properties push…
thmsobrmlr Mar 7, 2024
c9af7b4
most of test_correlation_with_multiple_properties
thmsobrmlr Mar 7, 2024
fb31342
Update query snapshots
github-actions[bot] Mar 7, 2024
9923b1e
Update query snapshots
github-actions[bot] Mar 7, 2024
ffaa1d0
Update UI snapshots for `webkit` (2)
github-actions[bot] Mar 7, 2024
fb8c962
Update UI snapshots for `webkit` (2)
github-actions[bot] Mar 7, 2024
e6f0457
Update UI snapshots for `webkit` (2)
github-actions[bot] Mar 7, 2024
91f9058
Update UI snapshots for `webkit` (2)
github-actions[bot] Mar 7, 2024
86c0665
Update UI snapshots for `chromium` (2)
github-actions[bot] Mar 7, 2024
8f091b6
Update UI snapshots for `chromium` (2)
github-actions[bot] Mar 7, 2024
61d01b8
fix groups
thmsobrmlr Mar 7, 2024
47b9992
fix test_funnel_correlation_with_properties_and_groups
thmsobrmlr Mar 7, 2024
6129f04
test_funnel_correlation_with_properties_and_groups_person_on_events
thmsobrmlr Mar 7, 2024
909d964
fixes
thmsobrmlr Mar 7, 2024
8545800
types
thmsobrmlr Mar 7, 2024
82b00ff
fixes
thmsobrmlr Mar 7, 2024
98743f1
Update UI snapshots for `chromium` (2)
github-actions[bot] Mar 7, 2024
2bd0281
Update UI snapshots for `chromium` (2)
github-actions[bot] Mar 7, 2024
e001296
Update UI snapshots for `webkit` (2)
github-actions[bot] Mar 7, 2024
38b9d51
Update UI snapshots for `webkit` (2)
github-actions[bot] Mar 7, 2024
aec3286
Update UI snapshots for `chromium` (1)
github-actions[bot] Mar 7, 2024
b8ca16d
Update UI snapshots for `chromium` (1)
github-actions[bot] Mar 7, 2024
703af1b
Update query snapshots
github-actions[bot] Mar 12, 2024
90d32e1
Update UI snapshots for `chromium` (2)
github-actions[bot] Mar 12, 2024
40634e9
Update query snapshots
github-actions[bot] Mar 12, 2024
ad20a91
Update UI snapshots for `chromium` (2)
github-actions[bot] Mar 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 43 additions & 7 deletions frontend/src/queries/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@
{
"$ref": "#/definitions/FunnelsActorsQuery"
},
{
"$ref": "#/definitions/FunnelCorrelationActorsQuery"
},
{
"$ref": "#/definitions/HogQLQuery"
}
Expand Down Expand Up @@ -1564,6 +1567,38 @@
"enum": ["second", "minute", "hour", "day", "week", "month"],
"type": "string"
},
"FunnelCorrelationActorsQuery": {
"additionalProperties": false,
"properties": {
"funnelCorrelationPersonConverted": {
"type": "boolean"
},
"funnelCorrelationPersonEntity": {
"$ref": "#/definitions/AnyEntityNode"
},
"funnelCorrelationPropertyValues": {
"items": {
"$ref": "#/definitions/AnyPropertyFilter"
},
"type": "array"
},
"includeRecordings": {
"type": "boolean"
},
"kind": {
"const": "FunnelCorrelationActorsQuery",
"type": "string"
},
"response": {
"$ref": "#/definitions/ActorsQueryResponse"
},
"source": {
"$ref": "#/definitions/FunnelCorrelationQuery"
}
},
"required": ["kind", "source"],
"type": "object"
},
"FunnelCorrelationQuery": {
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -1643,9 +1678,7 @@
"type": "array"
},
"types": {
"items": {
"type": "string"
},
"items": {},
"type": "array"
}
},
Expand Down Expand Up @@ -1983,7 +2016,7 @@
"type": "boolean"
},
"kind": {
"const": "InsightActorsQuery",
"const": "FunnelsActorsQuery",
"type": "string"
},
"response": {
Expand Down Expand Up @@ -2663,6 +2696,9 @@
},
{
"$ref": "#/definitions/FunnelsActorsQuery"
},
{
"$ref": "#/definitions/FunnelCorrelationActorsQuery"
}
]
}
Expand Down Expand Up @@ -3118,6 +3154,8 @@
"HogQLMetadata",
"HogQLAutocomplete",
"ActorsQuery",
"FunnelsActorsQuery",
"FunnelCorrelationActorsQuery",
"SessionsTimelineQuery",
"DataTableNode",
"DataVisualizationNode",
Expand Down Expand Up @@ -4266,9 +4304,7 @@
"type": "array"
},
"types": {
"items": {
"type": "string"
},
"items": {},
"type": "array"
}
},
Expand Down
18 changes: 14 additions & 4 deletions frontend/src/queries/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export enum NodeKind {
HogQLMetadata = 'HogQLMetadata',
HogQLAutocomplete = 'HogQLAutocomplete',
ActorsQuery = 'ActorsQuery',
FunnelsActorsQuery = 'FunnelsActorsQuery',
FunnelCorrelationActorsQuery = 'FunnelCorrelationActorsQuery',
SessionsTimelineQuery = 'SessionsTimelineQuery',

// Interface nodes
Expand Down Expand Up @@ -921,7 +923,7 @@ export interface ActorsQueryResponse {

export interface ActorsQuery extends DataNode {
kind: NodeKind.ActorsQuery
source?: InsightActorsQuery | FunnelsActorsQuery | HogQLQuery
source?: InsightActorsQuery | FunnelsActorsQuery | FunnelCorrelationActorsQuery | HogQLQuery
select?: HogQLExpression[]
search?: string
properties?: AnyPropertyFilter[]
Expand Down Expand Up @@ -1090,7 +1092,7 @@ export interface InsightActorsQuery<T extends InsightsQueryBase = InsightQuerySo
}

export interface FunnelsActorsQuery extends InsightActorsQueryBase {
kind: NodeKind.InsightActorsQuery
kind: NodeKind.FunnelsActorsQuery
source: FunnelsQuery
/** Index of the step for which we want to get the timestamp for, per person.
* Positive for converted persons, negative for dropped of persons. */
Expand All @@ -1105,6 +1107,14 @@ export interface FunnelsActorsQuery extends InsightActorsQueryBase {
funnelTrendsEntrancePeriodStart?: string
}

export interface FunnelCorrelationActorsQuery extends InsightActorsQueryBase {
kind: NodeKind.FunnelCorrelationActorsQuery
source: FunnelCorrelationQuery
funnelCorrelationPersonConverted?: boolean
funnelCorrelationPersonEntity?: AnyEntityNode
funnelCorrelationPropertyValues?: AnyPropertyFilter[]
}

export interface EventDefinition {
event: string
properties: Record<string, any>
Expand All @@ -1127,7 +1137,7 @@ export interface FunnelCorrelationResult {
export interface FunnelCorrelationResponse {
results: FunnelCorrelationResult
columns?: any[]
types?: string[]
types?: any[]
hogql?: string
timings?: QueryTiming[]
hasMore?: boolean
Expand Down Expand Up @@ -1188,7 +1198,7 @@ export interface InsightActorsQueryOptionsResponse {

export interface InsightActorsQueryOptions {
kind: NodeKind.InsightActorsQueryOptions
source: InsightActorsQuery | FunnelsActorsQuery
source: InsightActorsQuery | FunnelsActorsQuery | FunnelCorrelationActorsQuery
response?: InsightActorsQueryOptionsResponse
}

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/scenes/funnels/FunnelLineGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export function FunnelLineGraph({

if (hogQLInsightsFunnelsFlagEnabled) {
const query: FunnelsActorsQuery = {
kind: NodeKind.InsightActorsQuery,
kind: NodeKind.FunnelsActorsQuery,
source: querySource,
funnelTrendsDropOff: false,
funnelTrendsEntrancePeriodStart: dayjs(day).format('YYYY-MM-DD HH:mm:ss'),
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/scenes/funnels/funnelCorrelationLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const funnelCorrelationLogic = kea<funnelCorrelationLogicType>([
try {
if (values.hogQLInsightsFunnelsFlagEnabled) {
const actorsQuery: FunnelsActorsQuery = {
kind: NodeKind.InsightActorsQuery,
kind: NodeKind.FunnelsActorsQuery,
source: values.querySource!,
}
const query: FunnelCorrelationQuery = {
Expand Down Expand Up @@ -93,7 +93,7 @@ export const funnelCorrelationLogic = kea<funnelCorrelationLogicType>([
loadEventWithPropertyCorrelations: async (eventName: string) => {
if (values.hogQLInsightsFunnelsFlagEnabled) {
const actorsQuery: FunnelsActorsQuery = {
kind: NodeKind.InsightActorsQuery,
kind: NodeKind.FunnelsActorsQuery,
source: values.querySource!,
}
const query: FunnelCorrelationQuery = {
Expand Down
164 changes: 145 additions & 19 deletions frontend/src/scenes/funnels/funnelPersonsModalLogic.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import { actions, connect, kea, key, listeners, path, props, selectors } from 'kea'
import { elementsToAction } from 'scenes/events/createActionFromEvent'
import { insightLogic } from 'scenes/insights/insightLogic'
import { keyForInsightLogicProps } from 'scenes/insights/sharedUtils'
import { funnelTitle } from 'scenes/trends/persons-modal/persons-modal-utils'
import { openPersonsModal } from 'scenes/trends/persons-modal/PersonsModal'

import { FunnelsActorsQuery, NodeKind } from '~/queries/schema'
import {
EventsNode,
FunnelCorrelationActorsQuery,
FunnelCorrelationQuery,
FunnelsActorsQuery,
NodeKind,
} from '~/queries/schema'
import {
AnyPropertyFilter,
FunnelCorrelation,
FunnelCorrelationResultsType,
FunnelStep,
FunnelStepWithConversionMetrics,
InsightLogicProps,
PropertyFilterType,
PropertyOperator,
} from '~/types'

import { funnelDataLogic } from './funnelDataLogic'
Expand Down Expand Up @@ -99,7 +109,7 @@ export const funnelPersonsModalLogic = kea<funnelPersonsModalLogicType>([
// openPersonsModalForStep is for the baseline - for breakdown series use openPersonsModalForSeries
if (values.hogQLInsightsFunnelsFlagEnabled) {
const query: FunnelsActorsQuery = {
kind: NodeKind.InsightActorsQuery,
kind: NodeKind.FunnelsActorsQuery,
source: values.querySource!,
funnelStep: converted ? stepNo : -stepNo,
includeRecordings: true,
Expand Down Expand Up @@ -131,7 +141,7 @@ export const funnelPersonsModalLogic = kea<funnelPersonsModalLogicType>([
// Version of openPersonsModalForStep that accurately handles breakdown series
if (values.hogQLInsightsFunnelsFlagEnabled) {
const query: FunnelsActorsQuery = {
kind: NodeKind.InsightActorsQuery,
kind: NodeKind.FunnelsActorsQuery,
source: values.querySource!,
funnelStep: converted ? stepNo : -stepNo,
funnelStepBreakdown: series.breakdown_value,
Expand All @@ -152,26 +162,142 @@ export const funnelPersonsModalLogic = kea<funnelPersonsModalLogicType>([

if (correlation.result_type === FunnelCorrelationResultsType.Properties) {
const { breakdown, breakdown_value } = parseBreakdownValue(correlation.event.event)
openPersonsModal({
url: success ? correlation.success_people_url : correlation.failure_people_url,
title: funnelTitle({
converted: success,
step: values.steps.length,
breakdown_value,
label: breakdown,
}),
const title = funnelTitle({
converted: success,
step: values.steps.length,
breakdown_value,
label: breakdown,
})

if (values.hogQLInsightsFunnelsFlagEnabled) {
// properties
const [propertyName, propertyValue] = correlation.event.event.split('::')
const propType = values.querySource?.aggregation_group_type_index ? 'group' : 'person'
const actorsQuery: FunnelsActorsQuery = {
kind: NodeKind.FunnelsActorsQuery,
source: values.querySource!,
funnelStep: 1,
includeRecordings: true,
}
const correlationQuery: FunnelCorrelationQuery = {
kind: NodeKind.FunnelCorrelationQuery,
source: actorsQuery,
funnelCorrelationType: correlation.result_type,
}
const query: FunnelCorrelationActorsQuery = {
kind: NodeKind.FunnelCorrelationActorsQuery,
source: correlationQuery,
funnelCorrelationPersonConverted: success,
funnelCorrelationPropertyValues: [
{
key: propertyName,
value: propertyValue,
type: propType === 'person' ? PropertyFilterType.Person : PropertyFilterType.Group,
operator: PropertyOperator.Exact,
group_type_index: values.querySource?.aggregation_group_type_index,
},
],
}
openPersonsModal({
title,
query,
additionalSelect: { matched_recordings: 'matched_recordings' },
})
} else {
openPersonsModal({
url: success ? correlation.success_people_url : correlation.failure_people_url,
title,
})
}
} else {
const { name } = parseEventAndProperty(correlation.event)

openPersonsModal({
url: success ? correlation.success_people_url : correlation.failure_people_url,
title: funnelTitle({
converted: success,
step: values.steps.length,
label: name,
}),
const title = funnelTitle({
converted: success,
step: values.steps.length,
label: name,
})

if (values.hogQLInsightsFunnelsFlagEnabled) {
const actorsQuery: FunnelsActorsQuery = {
kind: NodeKind.FunnelsActorsQuery,
source: values.querySource!,
funnelStep: 1,
includeRecordings: true,
}
const correlationQuery: FunnelCorrelationQuery = {
kind: NodeKind.FunnelCorrelationQuery,
source: actorsQuery,
funnelCorrelationType: correlation.result_type,
}

let entity: EventsNode
if (correlation.result_type === FunnelCorrelationResultsType.Events) {
// events
entity = {
event: correlation.event.event,
kind: NodeKind.EventsNode,
}
} else {
// events with properties
const eventName = correlation.event.event.split('::')[0]

let properties: AnyPropertyFilter[]
if (eventName === '$autocapture') {
// If we have an $autocapture event, we need to
// convert the `elements` chain into an "action".
const elements = correlation.event.elements
const elementsAsAction = elementsToAction(elements)
properties = Object.entries(elementsAsAction)
.map(([propertyKey, propertyValue]) => {
if (propertyValue !== null) {
return {
key: propertyKey,
value: [propertyValue],
type: 'element',
operator: 'exact',
}
}
})
.filter(Boolean) as AnyPropertyFilter[]
} else {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, propertyName, propertyValue] = correlation.event.event.split('::')

properties = [
{
key: propertyName,
value: propertyValue,
type: PropertyFilterType.Event,
operator: PropertyOperator.Exact,
},
]
}

entity = {
kind: NodeKind.EventsNode,
event: eventName,
properties,
}
}

const query: FunnelCorrelationActorsQuery = {
kind: NodeKind.FunnelCorrelationActorsQuery,
source: correlationQuery,
funnelCorrelationPersonConverted: success,
funnelCorrelationPersonEntity: entity,
}

openPersonsModal({
title,
query,
additionalSelect: { matched_recordings: 'matched_recordings' },
})
} else {
openPersonsModal({
url: success ? correlation.success_people_url : correlation.failure_people_url,
title,
})
}
}
},
})),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export const funnelPropertyCorrelationLogic = kea<funnelPropertyCorrelationLogic
try {
if (values.hogQLInsightsFunnelsFlagEnabled) {
const actorsQuery: FunnelsActorsQuery = {
kind: NodeKind.InsightActorsQuery,
kind: NodeKind.FunnelsActorsQuery,
source: values.querySource!,
}
const query: FunnelCorrelationQuery = {
Expand Down
Loading
Loading