def _retrieve_people(self, target_entity: Entity, filter: StickinessFilter, team: Team) -> ReturnDict: from posthog.api.person import PersonSerializer if target_entity.type == TREND_FILTER_TYPE_EVENTS: filtered_events = base.process_entity_for_events(target_entity, team_id=team.pk, order_by=None).filter( base.filter_events(team.pk, filter, target_entity) ) elif target_entity.type == TREND_FILTER_TYPE_ACTIONS: actions = Action.objects.filter(deleted=False, team=team) actions = actions.prefetch_related(Prefetch("steps", queryset=ActionStep.objects.order_by("id"))) try: actions.get(pk=target_entity.id) except Action.DoesNotExist: return PersonSerializer([], many=True).data filtered_events = base.process_entity_for_events(target_entity, team_id=team.pk, order_by=None).filter( base.filter_events(team.pk, filter, target_entity) ) else: raise ValueError("target entity must be action or event") events = ( filtered_events.values("person_id") .annotate(day_count=Count(filter.trunc_func("timestamp"), distinct=True)) .filter(day_count=filter.selected_interval) ) people = Person.objects.filter( team=team, id__in=[p["person_id"] for p in events[filter.offset : filter.offset + 100]], ) people = people.prefetch_related(Prefetch("persondistinctid_set", to_attr="distinct_ids_cache")) return PersonSerializer(people, many=True).data
def stickiness(self, entity: Entity, filter: StickinessFilter, team_id: int) -> Dict[str, Any]: events = process_entity_for_events(entity=entity, team_id=team_id, order_by=None,) events = events.filter(filter_events(team_id, filter, entity)) events = ( events.filter(filter_events(team_id, filter, entity)) .values("person_id") .annotate(interval_count=Count(filter.trunc_func("timestamp"), distinct=True)) .filter(interval_count__lte=filter.total_intervals) ) events_sql, events_sql_params = events.query.sql_with_params() aggregated_query = "select count(v.person_id), v.interval_count from ({}) as v group by v.interval_count".format( events_sql ) counts = execute_custom_sql(aggregated_query, events_sql_params) return self.process_result(counts, filter)
def stickiness_format_intervals(events: QuerySet, filter: StickinessFilter) -> QuerySet: return (events.values("person_id").annotate( day_count=Count(filter.trunc_func("timestamp"), distinct=True)).filter( day_count=filter.selected_interval))