Example #1
0
    def calculate_funnel_correlation_persons(
        self, request: request.Request
    ) -> Dict[str, Tuple[list, Optional[str], Optional[str]]]:
        if request.user.is_anonymous or not self.team:
            return {"result": ([], None, None)}

        filter = Filter(request=request, data={"insight": INSIGHT_FUNNELS}, team=self.team)
        if not filter.correlation_person_limit:
            filter = filter.with_data({FUNNEL_CORRELATION_PERSON_LIMIT: 100})
        base_uri = request.build_absolute_uri("/")
        actors, serialized_actors = FunnelCorrelationActors(
            filter=filter, team=self.team, base_uri=base_uri
        ).get_actors()
        _should_paginate = should_paginate(actors, filter.correlation_person_limit)

        next_url = (
            format_query_params_absolute_url(
                request,
                filter.correlation_person_offset + filter.correlation_person_limit,
                offset_alias=FUNNEL_CORRELATION_PERSON_OFFSET,
                limit_alias=FUNNEL_CORRELATION_PERSON_LIMIT,
            )
            if _should_paginate
            else None
        )
        initial_url = format_query_params_absolute_url(request, 0)

        # cached_function expects a dict with the key result
        return {"result": (serialized_actors, next_url, initial_url)}
Example #2
0
    def test_people_arent_returned_multiple_times(self):

        people = journeys_for(
            {
                "user_1": [
                    {"event": "user signed up", "timestamp": datetime(2020, 1, 2, 14)},
                    {"event": "positively_related", "timestamp": datetime(2020, 1, 3, 14)},
                    # duplicate event
                    {"event": "positively_related", "timestamp": datetime(2020, 1, 3, 14)},
                    {"event": "paid", "timestamp": datetime(2020, 1, 4, 14)},
                ]
            },
            self.team,
        )

        filter = Filter(
            data={
                "events": [
                    {"id": "user signed up", "type": "events", "order": 0},
                    {"id": "paid", "type": "events", "order": 1},
                ],
                "insight": INSIGHT_FUNNELS,
                "date_from": "2020-01-01",
                "date_to": "2020-01-14",
                "funnel_correlation_type": "events",
                "funnel_correlation_person_entity": {"id": "positively_related", "type": "events"},
                "funnel_correlation_person_converted": "TrUe",
            }
        )
        _, serialized_actors = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertCountEqual([str(val["id"]) for val in serialized_actors], [str(people["user_1"].uuid)])
Example #3
0
    def test_funnel_correlation_on_properties_with_recordings(self):
        p1 = _create_person(distinct_ids=["user_1"], team=self.team, properties={"foo": "bar"})
        _create_event(
            event="$pageview",
            distinct_id="user_1",
            team=self.team,
            timestamp=timezone.now(),
            properties={"$session_id": "s2", "$window_id": "w1"},
            event_uuid="11111111-1111-1111-1111-111111111111",
        )
        _create_event(
            event="insight analyzed",
            distinct_id="user_1",
            team=self.team,
            timestamp=(timezone.now() + timedelta(minutes=3)),
            properties={"$session_id": "s2", "$window_id": "w2"},
            event_uuid="21111111-1111-1111-1111-111111111111",
        )

        _create_session_recording_event(self.team.pk, "user_1", "s2", datetime(2021, 1, 2, 0, 0, 0))

        # Success filter
        filter = Filter(
            data={
                "insight": INSIGHT_FUNNELS,
                "date_from": "2021-01-01",
                "date_to": "2021-01-08",
                "funnel_correlation_type": "properties",
                "events": [{"id": "$pageview", "order": 0}, {"id": "insight analyzed", "order": 1}],
                "include_recordings": "true",
                "funnel_correlation_property_values": [
                    {"key": "foo", "value": "bar", "operator": "exact", "type": "person"}
                ],
                "funnel_correlation_person_converted": "True",
            }
        )
        _, results = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertEqual(results[0]["id"], p1.uuid)
        self.assertEqual(
            results[0]["matched_recordings"],
            [
                {
                    "events": [
                        {
                            "timestamp": timezone.now() + timedelta(minutes=3),
                            "uuid": UUID("21111111-1111-1111-1111-111111111111"),
                            "window_id": "w2",
                        }
                    ],
                    "session_id": "s2",
                }
            ],
        )
Example #4
0
def insert_cohort_actors_into_ch(cohort: Cohort, filter_data: Dict):
    insight_type = filter_data.get("insight")
    query_builder: ActorBaseQuery

    if insight_type == INSIGHT_TRENDS:
        filter = Filter(data=filter_data, team=cohort.team)
        entity = get_target_entity(filter)
        query_builder = ClickhouseTrendsActors(cohort.team, entity, filter)
    elif insight_type == INSIGHT_STICKINESS:
        stickiness_filter = StickinessFilter(data=filter_data,
                                             team=cohort.team)
        entity = get_target_entity(stickiness_filter)
        query_builder = ClickhouseStickinessActors(cohort.team, entity,
                                                   stickiness_filter)
    elif insight_type == INSIGHT_FUNNELS:
        funnel_filter = Filter(data=filter_data, team=cohort.team)
        if funnel_filter.correlation_person_entity:
            query_builder = FunnelCorrelationActors(filter=funnel_filter,
                                                    team=cohort.team)
        else:
            funnel_actor_class = get_funnel_actor_class(funnel_filter)
            query_builder = funnel_actor_class(filter=funnel_filter,
                                               team=cohort.team)
    elif insight_type == INSIGHT_PATHS:
        path_filter = PathFilter(data=filter_data, team=cohort.team)
        query_builder = ClickhousePathsActors(path_filter,
                                              cohort.team,
                                              funnel_filter=None)
    else:
        if settings.DEBUG:
            raise ValueError(
                f"Insight type: {insight_type} not supported for cohort creation"
            )
        else:
            capture_exception(
                Exception(
                    f"Insight type: {insight_type} not supported for cohort creation"
                ))

    if query_builder.is_aggregating_by_groups:
        if settings.DEBUG:
            raise ValueError(
                f"Query type: Group based queries are not supported for cohort creation"
            )
        else:
            capture_exception(
                Exception(
                    f"Query type: Group based queries are not supported for cohort creation"
                ))
    else:
        query, params = query_builder.actor_query(limit_actors=False)

    insert_actors_into_cohort_by_query(cohort, query, params)
Example #5
0
    def test_strict_funnel_correlation_with_recordings(self):

        # First use that successfully completes the strict funnel
        p1 = _create_person(distinct_ids=["user_1"], team=self.team, properties={"foo": "bar"})
        _create_event(
            event="$pageview",
            distinct_id="user_1",
            team=self.team,
            timestamp=timezone.now(),
            properties={"$session_id": "s2", "$window_id": "w1"},
            event_uuid="11111111-1111-1111-1111-111111111111",
        )
        _create_event(
            event="insight analyzed",
            distinct_id="user_1",
            team=self.team,
            timestamp=(timezone.now() + timedelta(minutes=3)),
            properties={"$session_id": "s2", "$window_id": "w2"},
            event_uuid="31111111-1111-1111-1111-111111111111",
        )
        _create_event(
            event="insight analyzed",  # Second event should not be returned
            distinct_id="user_1",
            team=self.team,
            timestamp=(timezone.now() + timedelta(minutes=4)),
            properties={"$session_id": "s2", "$window_id": "w2"},
            event_uuid="41111111-1111-1111-1111-111111111111",
        )
        _create_session_recording_event(self.team.pk, "user_1", "s2", datetime(2021, 1, 2, 0, 0, 0))

        # Second user with strict funnel drop off, but completed the step events for a normal funnel
        p2 = _create_person(distinct_ids=["user_2"], team=self.team, properties={"foo": "bar"})
        _create_event(
            event="$pageview",
            distinct_id="user_2",
            team=self.team,
            timestamp=timezone.now(),
            properties={"$session_id": "s3", "$window_id": "w1"},
            event_uuid="51111111-1111-1111-1111-111111111111",
        )
        _create_event(
            event="insight loaded",  # Interupting event
            distinct_id="user_2",
            team=self.team,
            timestamp=(timezone.now() + timedelta(minutes=3)),
            properties={"$session_id": "s3", "$window_id": "w2"},
            event_uuid="61111111-1111-1111-1111-111111111111",
        )
        _create_event(
            event="insight analyzed",
            distinct_id="user_2",
            team=self.team,
            timestamp=(timezone.now() + timedelta(minutes=4)),
            properties={"$session_id": "s3", "$window_id": "w2"},
            event_uuid="71111111-1111-1111-1111-111111111111",
        )
        _create_session_recording_event(self.team.pk, "user_2", "s3", datetime(2021, 1, 2, 0, 0, 0))

        # Success filter
        filter = Filter(
            data={
                "insight": INSIGHT_FUNNELS,
                "date_from": "2021-01-01",
                "date_to": "2021-01-08",
                "funnel_order_type": "strict",
                "funnel_correlation_type": "properties",
                "events": [{"id": "$pageview", "order": 0}, {"id": "insight analyzed", "order": 1}],
                "include_recordings": "true",
                "funnel_correlation_property_values": [
                    {"key": "foo", "value": "bar", "operator": "exact", "type": "person"}
                ],
                "funnel_correlation_person_converted": "True",
            }
        )
        _, results = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertEqual(len(results), 1)
        self.assertEqual(results[0]["id"], p1.uuid)
        self.assertEqual(
            results[0]["matched_recordings"],
            [
                {
                    "events": [
                        {
                            "timestamp": timezone.now() + timedelta(minutes=3),
                            "uuid": UUID("31111111-1111-1111-1111-111111111111"),
                            "window_id": "w2",
                        }
                    ],
                    "session_id": "s2",
                }
            ],
        )

        # Drop off filter
        filter = Filter(
            data={
                "insight": INSIGHT_FUNNELS,
                "date_from": "2021-01-01",
                "date_to": "2021-01-08",
                "funnel_order_type": "strict",
                "funnel_correlation_type": "properties",
                "events": [{"id": "$pageview", "order": 0}, {"id": "insight analyzed", "order": 1}],
                "include_recordings": "true",
                "funnel_correlation_property_values": [
                    {"key": "foo", "value": "bar", "operator": "exact", "type": "person"}
                ],
                "funnel_correlation_person_converted": "False",
            }
        )
        _, results = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertEqual(results[0]["id"], p2.uuid)
        self.assertEqual(
            results[0]["matched_recordings"],
            [
                {
                    "events": [
                        {
                            "timestamp": timezone.now(),
                            "uuid": UUID("51111111-1111-1111-1111-111111111111"),
                            "window_id": "w1",
                        }
                    ],
                    "session_id": "s3",
                }
            ],
        )
Example #6
0
    def test_basic_funnel_correlation_with_events(self):
        filter, success_target_persons, failure_target_persons, person_fail, person_succ = self._setup_basic_test()

        # test positively_related successes
        filter = filter.with_data(
            {
                "funnel_correlation_person_entity": {"id": "positively_related", "type": "events"},
                "funnel_correlation_person_converted": "TrUe",
            }
        )
        _, serialized_actors = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertCountEqual([str(val["id"]) for val in serialized_actors], success_target_persons)

        # test negatively_related failures
        filter = filter.with_data(
            {
                "funnel_correlation_person_entity": {"id": "negatively_related", "type": "events"},
                "funnel_correlation_person_converted": "falsE",
            }
        )

        _, serialized_actors = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertCountEqual([str(val["id"]) for val in serialized_actors], failure_target_persons)

        # test positively_related failures
        filter = filter.with_data(
            {
                "funnel_correlation_person_entity": {"id": "positively_related", "type": "events"},
                "funnel_correlation_person_converted": "False",
            }
        )
        _, serialized_actors = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertCountEqual([str(val["id"]) for val in serialized_actors], [str(person_fail.uuid)])

        # test negatively_related successes
        filter = filter.with_data(
            {
                "funnel_correlation_person_entity": {"id": "negatively_related", "type": "events"},
                "funnel_correlation_person_converted": "trUE",
            }
        )
        _, serialized_actors = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertCountEqual([str(val["id"]) for val in serialized_actors], [str(person_succ.uuid)])

        # test all positively_related
        filter = filter.with_data(
            {
                "funnel_correlation_person_entity": {"id": "positively_related", "type": "events"},
                "funnel_correlation_person_converted": None,
            }
        )
        _, serialized_actors = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertCountEqual(
            [str(val["id"]) for val in serialized_actors], [*success_target_persons, str(person_fail.uuid)]
        )

        # test all negatively_related
        filter = filter.with_data(
            {
                "funnel_correlation_person_entity": {"id": "negatively_related", "type": "events"},
                "funnel_correlation_person_converted": None,
            }
        )
        _, serialized_actors = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertCountEqual(
            [str(val["id"]) for val in serialized_actors], [*failure_target_persons, str(person_succ.uuid)]
        )