Example #1
0
    def _breakdown_prop_params(self, aggregate_operation: str,
                               math_params: Dict):
        values_arr = get_breakdown_prop_values(
            self.filter,
            self.entity,
            aggregate_operation,
            self.team_id,
            extra_params=math_params,
            column_optimizer=self.column_optimizer,
        )

        # :TRICKY: We only support string breakdown for event/person properties
        assert isinstance(self.filter.breakdown, str)

        if self.filter.breakdown_type == "person":
            breakdown_value, _ = get_property_string_expr(
                "person", self.filter.breakdown, "%(key)s", "person_props")
        elif self.filter.breakdown_type == "group":
            properties_field = f"group_properties_{self.filter.breakdown_group_type_index}"
            breakdown_value, _ = get_property_string_expr(
                "groups", self.filter.breakdown, "%(key)s", properties_field)
        else:
            breakdown_value, _ = get_property_string_expr(
                "events", self.filter.breakdown, "%(key)s", "properties")

        return (
            {
                "values": values_arr
            },
            BREAKDOWN_PROP_JOIN_SQL,
            {
                "breakdown_value_expr": breakdown_value
            },
            breakdown_value,
        )
Example #2
0
    def _get_breakdown_conditions(self) -> str:
        if self._filter.breakdown:
            limit = self._filter.breakdown_limit_or_default
            first_entity = self._filter.entities[0]

            values = get_breakdown_prop_values(self._filter,
                                               first_entity,
                                               "count(*)",
                                               self._team.pk,
                                               limit,
                                               extra_params={"offset": 0})
            # For people, pagination sets the offset param, which is common across filters
            # and gives us the wrong breakdown values here, so we override it.
            # For events, we assume breakdown values remain stable across the funnel,
            # so using just the first entity to get breakdown values is ok.

            self.params.update({"breakdown_values": values})

        return ""
Example #3
0
    def _get_breakdown_conditions(self) -> Optional[str]:
        """
        For people, pagination sets the offset param, which is common across filters
        and gives us the wrong breakdown values here, so we override it.
        For events, we assume breakdown values remain stable across the funnel,
        so using just the first entity to get breakdown values is ok.
        if this is a multi property breakdown then the breakdown values are misleading
        e.g. [Chrome, Safari], [95, 15] doesn't make clear that Chrome 15 isn't valid but Safari 15 is
        so the generated list here must be [[Chrome, 95], [Safari, 15]]
        """
        if self._filter.breakdown:
            limit = self._filter.breakdown_limit_or_default
            first_entity = self._filter.entities[0]

            return get_breakdown_prop_values(self._filter,
                                             first_entity,
                                             "count(*)",
                                             self._team.pk,
                                             limit,
                                             extra_params={"offset": 0})

        return None
Example #4
0
    def test_breakdown_person_props(self):
        p1 = Person.objects.create(team_id=self.team.pk,
                                   distinct_ids=["p1"],
                                   properties={"$browser": "test"})
        _create_event(
            team=self.team,
            event="$pageview",
            distinct_id="p1",
            timestamp="2020-01-02T12:00:00Z",
            properties={"key": "val"},
        )

        self.team.test_account_filters = [
            {
                "key": "email",
                "type": "person",
                "value": "posthog.com",
                "operator": "not_icontains"
            },
            {
                "key":
                "$host",
                "type":
                "event",
                "value": [
                    "127.0.0.1:3000", "127.0.0.1:5000", "localhost:5000",
                    "localhost:8000"
                ],
                "operator":
                "is_not",
            },
            {
                "key": "distinct_id",
                "type": "event",
                "value": "posthog.com",
                "operator": "not_icontains"
            },
        ]
        self.team.save()
        with freeze_time("2020-01-04T13:01:01Z"):
            filter = Filter(
                data={
                    "insight":
                    "FUNNELS",
                    "properties": [],
                    "filter_test_accounts":
                    True,
                    "events": [{
                        "id": "$pageview",
                        "name": "$pageview",
                        "type": "events",
                        "order": 0
                    }],
                    "actions": [],
                    "funnel_viz_type":
                    "steps",
                    "display":
                    "FunnelViz",
                    "interval":
                    "day",
                    "breakdown":
                    "$browser",
                    "breakdown_type":
                    "person",
                    "date_from":
                    "-14d",
                    "funnel_window_days":
                    14,
                })
            res = get_breakdown_prop_values(
                filter, Entity({
                    "id": "$pageview",
                    "type": "events"
                }), "count(*)", self.team.pk, 5)
            self.assertEqual(res, ["test"])
Example #5
0
    def test_breakdown_group_props(self):
        GroupTypeMapping.objects.create(team=self.team,
                                        group_type="organization",
                                        group_type_index=0)
        GroupTypeMapping.objects.create(team=self.team,
                                        group_type="company",
                                        group_type_index=1)

        create_group(team_id=self.team.pk,
                     group_type_index=0,
                     group_key="org:5",
                     properties={"industry": "finance"})
        create_group(team_id=self.team.pk,
                     group_type_index=0,
                     group_key="org:6",
                     properties={"industry": "technology"})
        create_group(team_id=self.team.pk,
                     group_type_index=0,
                     group_key="org:7",
                     properties={"industry": "finance"})
        create_group(team_id=self.team.pk,
                     group_type_index=0,
                     group_key="org:8",
                     properties={
                         "industry": "another",
                         "out": 1
                     })
        create_group(team_id=self.team.pk,
                     group_type_index=1,
                     group_key="company:10",
                     properties={"industry": "foobar"})
        # :TRICKY: Test group type overlapping
        create_group(team_id=self.team.pk,
                     group_type_index=1,
                     group_key="org:8",
                     properties={"industry": "foobar"})

        for org_index in range(5, 9):
            _create_event(
                event="$pageview",
                distinct_id="person1",
                team=self.team,
                properties={"$group_0": f"org:{org_index}"},
                timestamp="2020-01-02T12:00:00Z",
            )

        filter = Filter(
            data={
                "date_from":
                "2020-01-01T00:00:00Z",
                "date_to":
                "2020-01-12T00:00:00Z",
                "breakdown":
                "industry",
                "breakdown_type":
                "group",
                "breakdown_group_type_index":
                0,
                "events": [{
                    "id": "$pageview",
                    "type": "events",
                    "order": 0,
                }],
                "properties": [{
                    "key": "out",
                    "value": "",
                    "type": "group",
                    "group_type_index": 0,
                    "operator": "is_not_set"
                }],
            },
            team=self.team,
        )
        result = get_breakdown_prop_values(filter, filter.entities[0],
                                           "count(*)", self.team.pk, 5)
        self.assertEqual(result, ["finance", "technology"])
Example #6
0
    def test_breakdown_person_props_with_entity_filter(self):
        p1 = Person.objects.create(team_id=self.team.pk,
                                   distinct_ids=["p1"],
                                   properties={"$browser": "test"})
        _create_event(
            team=self.team,
            event="$pageview",
            distinct_id="p1",
            timestamp="2020-01-02T12:00:00Z",
            properties={"key": "val"},
        )
        p1 = Person.objects.create(team_id=self.team.pk,
                                   distinct_ids=["p2"],
                                   properties={"$browser": "test2"})
        _create_event(
            team=self.team,
            event="$pageview",
            distinct_id="p2",
            timestamp="2020-01-02T12:00:00Z",
            properties={"key": "val"},
        )

        cohort = Cohort.objects.create(team=self.team,
                                       name="a",
                                       groups=[{
                                           "properties": {
                                               "$browser": "test"
                                           }
                                       }])
        cohort.calculate_people()
        cohort.calculate_people_ch()

        entity_params = [{
            "id":
            "$pageview",
            "name":
            "$pageview",
            "type":
            "events",
            "order":
            0,
            "properties": [{
                "key": "id",
                "value": cohort.pk,
                "type": "cohort"
            }],
        }]
        with self.settings(USE_PRECALCULATED_CH_COHORT_PEOPLE=True):
            with freeze_time("2020-01-04T13:01:01Z"):
                filter = Filter(
                    data={
                        "insight": "FUNNELS",
                        "properties": [],
                        "filter_test_accounts": False,
                        "events": entity_params,
                        "actions": [],
                        "funnel_viz_type": "steps",
                        "display": "FunnelViz",
                        "interval": "day",
                        "breakdown": "$browser",
                        "breakdown_type": "person",
                        "date_from": "-14d",
                        "funnel_window_days": 14,
                    })
                res = get_breakdown_prop_values(filter,
                                                Entity(entity_params[0]),
                                                "count(*)", self.team.pk, 5)
                self.assertEqual(res, ["test"])
Example #7
0
    def test_breakdown_person_props_with_entity_filter_and_or_props_with_partial_pushdown(
            self):
        Person.objects.create(team_id=self.team.pk,
                              distinct_ids=["p1"],
                              properties={
                                  "$browser": "test",
                                  "$os": "test"
                              })
        _create_event(
            team=self.team,
            event="$pageview",
            distinct_id="p1",
            timestamp="2020-01-02T12:00:00Z",
            properties={"key": "val"},
        )
        Person.objects.create(team_id=self.team.pk,
                              distinct_ids=["p2"],
                              properties={
                                  "$browser": "test2",
                                  "$os": "test2"
                              })
        _create_event(
            team=self.team,
            event="$pageview",
            distinct_id="p2",
            timestamp="2020-01-02T12:00:00Z",
            properties={"key": "val2"},
        )
        Person.objects.create(team_id=self.team.pk,
                              distinct_ids=["p3"],
                              properties={
                                  "$browser": "test3",
                                  "$os": "test3"
                              })
        _create_event(
            team=self.team,
            event="$pageview",
            distinct_id="p3",
            timestamp="2020-01-02T12:00:00Z",
            properties={"key": "val3"},
        )

        entity_params = [{
            "id":
            "$pageview",
            "name":
            "$pageview",
            "type":
            "events",
            "order":
            0,
            "properties": [{
                "key": "$browser",
                "type": "person",
                "value": "test",
                "operator": "icontains"
            }],
        }]
        with self.settings(USE_PRECALCULATED_CH_COHORT_PEOPLE=True):
            with freeze_time("2020-01-04T13:01:01Z"):
                filter = Filter(
                    data={
                        "insight": "FUNNELS",
                        "properties": {
                            "type":
                            "OR",
                            "values": [
                                {
                                    "key": "$os",
                                    "type": "person",
                                    "value": "test2",
                                    "operator": "exact"
                                },
                                {
                                    "key": "key",
                                    "type": "event",
                                    "value": "val",
                                    "operator": "exact"
                                },
                            ],
                        },
                        "filter_test_accounts": False,
                        "events": entity_params,
                        "actions": [],
                        "funnel_viz_type": "steps",
                        "display": "FunnelViz",
                        "interval": "day",
                        "breakdown": "$browser",
                        "breakdown_type": "person",
                        "date_from": "-14d",
                        "funnel_window_days": 14,
                    })
                res = sorted(
                    get_breakdown_prop_values(filter, Entity(entity_params[0]),
                                              "count(*)", self.team.pk, 5))
                self.assertEqual(res, ["test", "test2"])