Skip to content

Commit b71ede2

Browse files
authored
fix popular search (#2436)
1 parent 6d25db1 commit b71ede2

File tree

6 files changed

+45
-14
lines changed

6 files changed

+45
-14
lines changed

learning_resources/etl/posthog.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from learning_resources.exceptions import PostHogAuthenticationError, PostHogQueryError
1616
from learning_resources.models import LearningResource, LearningResourceViewEvent
17+
from learning_resources.utils import resource_upserted_actions
1718

1819
log = logging.getLogger(__name__)
1920

@@ -275,4 +276,13 @@ def load_posthog_lrd_view_events(
275276
List of LearningResourceViewEvent
276277
"""
277278

278-
return [load_posthog_lrd_view_event(event) for event in events]
279+
events = [load_posthog_lrd_view_event(event) for event in events]
280+
learning_resource_ids = {
281+
event.learning_resource_id for event in events if event is not None
282+
}
283+
284+
for resource_id in learning_resource_ids:
285+
learning_resource = LearningResource.objects.get(id=resource_id)
286+
resource_upserted_actions(learning_resource, percolate=False)
287+
288+
return events

learning_resources/etl/posthog_test.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@
1010
from faker import Faker
1111

1212
from learning_resources.etl import posthog
13-
from learning_resources.models import LearningResourceViewEvent
13+
from learning_resources.factories import LearningResourceFactory
14+
from learning_resources.models import LearningResource, LearningResourceViewEvent
1415
from main.test_utils import MockResponse
1516

1617
fake = Faker()
1718

1819

19-
def generate_fake_posthog_lr_properties():
20+
def generate_fake_posthog_lr_properties(learning_resource):
2021
"""
2122
Generate a fake set of properties for a PostHog event.
2223
@@ -27,16 +28,16 @@ def generate_fake_posthog_lr_properties():
2728

2829
return json.dumps(
2930
{
30-
"resourceType": fake.word(ext_word_list=["course", "program", "video"]),
31+
"resourceType": learning_resource.resource_type,
3132
"platformCode": random.randrange(0, 9999), # noqa: S311
32-
"resourceId": random.randrange(0, 9999), # noqa: S311
33+
"resourceId": learning_resource.id,
3334
"readableId": str(uuid.uuid4()),
3435
"event_date": fake.date_time().isoformat(),
3536
}
3637
)
3738

3839

39-
def generate_fake_posthog_query_event(**kwargs):
40+
def generate_fake_posthog_query_event(learning_resource=None, **kwargs):
4041
"""
4142
Generate a fake PostHog query event.
4243
@@ -47,11 +48,14 @@ def generate_fake_posthog_query_event(**kwargs):
4748
"""
4849

4950
# datetimes here are all naive because this is what PostHog returns.
50-
51+
if learning_resource is None:
52+
learning_resource = LearningResourceFactory.create()
5153
return [
5254
kwargs.get("uuid", str(uuid.uuid4())),
5355
kwargs.get("event", ""),
54-
kwargs.get("properties", generate_fake_posthog_lr_properties()),
56+
kwargs.get(
57+
"properties", generate_fake_posthog_lr_properties(learning_resource)
58+
),
5559
kwargs.get("timestamp", datetime.now().isoformat()), # noqa: DTZ005
5660
kwargs.get("distinct_id", ""),
5761
kwargs.get("elements_chain", ""),
@@ -68,6 +72,7 @@ def generate_fake_posthog_query_event(**kwargs):
6872

6973
def generate_hogql_query_result(result_count: int = 5):
7074
"""Return a faked-out HogQL result."""
75+
learning_resource = LearningResourceFactory.create()
7176

7277
return {
7378
"clickhouse": "",
@@ -98,7 +103,10 @@ def generate_hogql_query_result(result_count: int = 5):
98103
},
99104
"offset": None,
100105
"query": None,
101-
"results": [generate_fake_posthog_query_event() for _ in range(result_count)],
106+
"results": [
107+
generate_fake_posthog_query_event(learning_resource)
108+
for _ in range(result_count)
109+
],
102110
"timings": [],
103111
"types": [],
104112
}
@@ -111,6 +119,7 @@ def hogql_query_result():
111119
return generate_hogql_query_result()
112120

113121

122+
@pytest.mark.django_db
114123
@pytest.mark.parametrize(
115124
"skip_setting", [[None], ["ph_api_key"], ["ph_root_endpoint"], ["ph_project_id"]]
116125
)
@@ -245,10 +254,21 @@ def load_posthog_lrd_view_events(mocker):
245254

246255
mocker.patch("requests.post", side_effect=api_call_results)
247256

257+
upsert_mock = mocker.patch(
258+
"learning_resources.etl.posthog.resource_upserted_actions",
259+
autospec=True,
260+
)
248261
posthog_events = posthog.posthog_extract_lrd_view_events()
249262

250263
lr_events = posthog.posthog_transform_lrd_view_events(posthog_events)
251264

252265
stored_events = load_posthog_lrd_view_events(lr_events)
253266

254267
assert LearningResourceViewEvent.objects.count() == len(stored_events)
268+
learning_resource_ids = [
269+
event.learning_resource_id for event in stored_events if event is not None
270+
]
271+
learning_resource_ids = set(learning_resource_ids)
272+
for resource_id in learning_resource_ids:
273+
learning_resource = LearningResource.objects.get(id=resource_id)
274+
upsert_mock.assert_any_call(learning_resource, percolate=False)

learning_resources/management/commands/load_posthog_lrd_view_events.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
from django.core.management import BaseCommand
44

5-
from learning_resources.etl.pipelines import posthog_etl
65
from learning_resources.models import LearningResourceViewEvent
6+
from learning_resources.tasks import get_learning_resource_views
77

88

99
class Command(BaseCommand):
@@ -16,7 +16,8 @@ def handle(self, *args, **kwargs): # noqa: ARG002
1616

1717
self.stdout.write("Running the ETL pipeline...")
1818

19-
posthog_etl()
19+
task = get_learning_resource_views.delay()
20+
task.get()
2021

2122
ev_count = LearningResourceViewEvent.objects.count()
2223

learning_resources/models.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -515,9 +515,7 @@ def next_run(self) -> Optional["LearningResourceRun"]:
515515
@cached_property
516516
def views_count(self) -> int:
517517
"""Return the number of views for the resource."""
518-
return models.LearningResourceViewEvent.objects.filter(
519-
learning_resource=self
520-
).count()
518+
return LearningResourceViewEvent.objects.filter(learning_resource=self).count()
521519

522520
@cached_property
523521
def user_list_parents(self) -> list["LearningResourceRelationship"]:

learning_resources/tasks.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ def get_learning_resource_views():
421421
"""Load learning resource views from the PostHog ETL."""
422422

423423
pipelines.posthog_etl()
424+
clear_search_cache()
424425

425426

426427
@app.task(acks_late=True)

learning_resources_search/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class FilterConfig:
122122
"name": {"type": "keyword"},
123123
},
124124
},
125+
"views": {"type": "integer"},
125126
"pace": {
126127
"type": "nested",
127128
"properties": {

0 commit comments

Comments
 (0)