Skip to content

Commit df6033d

Browse files
committed
add is_learning_material filter show courses and programs first in default sort
1 parent 5fccaa2 commit df6033d

File tree

7 files changed

+163
-9
lines changed

7 files changed

+163
-9
lines changed

frontends/api/src/generated/v1/api.ts

Lines changed: 92 additions & 5 deletions
Large diffs are not rendered by default.

learning_resources_search/api.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
LEARN_SUGGEST_FIELDS = ["title.trigram", "description.trigram"]
4040
COURSENUM_SORT_FIELD = "course.course_numbers.sort_coursenum"
41-
DEFAULT_SORT = "-created_on"
41+
DEFAULT_SORT = ["is_learning_material", "-created_on"]
4242

4343

4444
def gen_content_file_id(content_file_id):
@@ -551,7 +551,7 @@ def construct_search(search_params):
551551
sort = generate_sort_clause(search_params)
552552
search = search.sort(sort)
553553
elif not search_params.get("q"):
554-
search = search.sort(DEFAULT_SORT)
554+
search = search.sort(*DEFAULT_SORT)
555555

556556
if search_params.get("endpoint") == CONTENT_FILE_TYPE:
557557
query_type_query = {"exists": {"field": "content_type"}}
@@ -598,7 +598,6 @@ def execute_learn_search(search_params):
598598
"""
599599

600600
search = construct_search(search_params)
601-
602601
return search.execute().to_dict()
603602

604603

learning_resources_search/api_test.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1428,6 +1428,7 @@ def test_execute_learn_search_for_learning_resource_query(opensearch):
14281428
"course.course_numbers.sort_coursenum",
14291429
"course.course_numbers.primary",
14301430
"resource_relations",
1431+
"is_learning_material",
14311432
]
14321433
},
14331434
}
@@ -1630,6 +1631,7 @@ def test_execute_learn_search_for_content_file_query(opensearch):
16301631
"course.course_numbers.sort_coursenum",
16311632
"course.course_numbers.primary",
16321633
"resource_relations",
1634+
"is_learning_material",
16331635
]
16341636
},
16351637
}
@@ -1760,7 +1762,7 @@ def test_document_percolation(opensearch, mocker):
17601762
[
17611763
("-views", None, [{"views": {"order": "desc"}}]),
17621764
("-views", "text", [{"views": {"order": "desc"}}]),
1763-
(None, None, [{"created_on": {"order": "desc"}}]),
1765+
(None, None, ["is_learning_material", {"created_on": {"order": "desc"}}]),
17641766
(None, "text", None),
17651767
],
17661768
)

learning_resources_search/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class FilterConfig:
7474
"platform": FilterConfig("platform.code"),
7575
"offered_by": FilterConfig("offered_by.code"),
7676
"learning_format": FilterConfig("learning_format.code"),
77+
"is_learning_material": FilterConfig("is_learning_material"),
7778
}
7879

7980
SEARCH_NESTED_FILTERS = {
@@ -368,4 +369,5 @@ class FilterConfig:
368369
"course.course_numbers.sort_coursenum",
369370
"course.course_numbers.primary",
370371
"resource_relations",
372+
"is_learning_material",
371373
]

learning_resources_search/serializers.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
from learning_resources_search.api import gen_content_file_id
3939
from learning_resources_search.constants import (
4040
CONTENT_FILE_TYPE,
41+
COURSE_TYPE,
42+
PROGRAM_TYPE,
4143
)
4244
from learning_resources_search.models import PercolateQuery
4345
from learning_resources_search.utils import remove_child_queries
@@ -79,6 +81,8 @@ def serialize_learning_resource_for_update(
7981
return {
8082
"resource_relations": {"name": "resource"},
8183
"created_on": learning_resource_obj.created_on,
84+
"is_learning_material": learning_resource_obj.resource_type
85+
not in [COURSE_TYPE, PROGRAM_TYPE],
8286
**serialized_data,
8387
}
8488

@@ -175,6 +179,7 @@ def to_representation(self, obj):
175179
"professional",
176180
"free",
177181
"learning_format",
182+
"is_learning_material",
178183
]
179184

180185
CONTENT_FILE_AGGREGATIONS = ["topic", "content_feature_type", "platform", "offered_by"]
@@ -261,6 +266,13 @@ class LearningResourcesSearchRequestSerializer(SearchRequestSerializer):
261266
default=None,
262267
help_text="True if the learning resource offers a certificate",
263268
)
269+
is_learning_material = ArrayWrappedBoolean(
270+
required=False,
271+
allow_null=True,
272+
default=None,
273+
help_text="True if the learning resource is a podcast, podcast episode, video, "
274+
"video playlist, or learning path",
275+
)
264276
certification_choices = CertificationType.as_tuple()
265277
certification_type = StringArrayField(
266278
required=False,

learning_resources_search/serializers_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@
142142
"url": "http://xpro.mit.edu/courses/course-v1:xPRO+MCPO+R1/",
143143
"resource_type": "course",
144144
"platform": "globalalumni",
145+
"is_learning_material": False,
145146
},
146147
}
147148
],
@@ -278,6 +279,7 @@
278279
"url": "http://xpro.mit.edu/courses/course-v1:xPRO+MCPO+R1/",
279280
"resource_type": "course",
280281
"platform": "globalalumni",
282+
"is_learning_material": False,
281283
}
282284
],
283285
"metadata": {
@@ -344,6 +346,7 @@
344346
"last_modified": None,
345347
"runs": [],
346348
"course_feature": [],
349+
"is_learning_material": True,
347350
"user_list_parents": [],
348351
},
349352
}
@@ -507,6 +510,7 @@
507510
"last_modified": None,
508511
"runs": [],
509512
"course_feature": [],
513+
"is_learning_material": True,
510514
"user_list_parents": [],
511515
}
512516
],
@@ -589,6 +593,7 @@ def test_serialize_learning_resource_for_bulk(resource_type, is_professional, no
589593
"_id": resource.id,
590594
"resource_relations": {"name": "resource"},
591595
"created_on": resource.created_on,
596+
"is_learning_material": resource.resource_type not in ["course", "program"],
592597
**free_dict,
593598
**LearningResourceSerializer(resource).data,
594599
}
@@ -635,6 +640,7 @@ def test_serialize_course_numbers_for_bulk(
635640
"resource_relations": {"name": "resource"},
636641
"created_on": resource.created_on,
637642
"free": False,
643+
"is_learning_material": False,
638644
**LearningResourceSerializer(resource).data,
639645
}
640646
expected_data["course"]["course_numbers"][0] = {
@@ -713,6 +719,7 @@ def test_learning_resources_search_request_serializer():
713719
"certification": "false",
714720
"certification_type": CertificationType.none.name,
715721
"free": True,
722+
"is_learning_material": True,
716723
"offered_by": "xpro,ocw",
717724
"platform": "xpro,edx,ocw",
718725
"topic": "Math",
@@ -730,6 +737,7 @@ def test_learning_resources_search_request_serializer():
730737
"sortby": "-start_date",
731738
"professional": [True],
732739
"certification": [False],
740+
"is_learning_material": [True],
733741
"certification_type": [CertificationType.none.name],
734742
"free": [True],
735743
"offered_by": ["xpro", "ocw"],

openapi/specs/v1.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2093,6 +2093,7 @@ paths:
20932093
- professional
20942094
- free
20952095
- learning_format
2096+
- is_learning_material
20962097
type: string
20972098
description: |-
20982099
* `resource_type` - resource_type
@@ -2107,6 +2108,7 @@ paths:
21072108
* `professional` - professional
21082109
* `free` - free
21092110
* `learning_format` - learning_format
2111+
* `is_learning_material` - is_learning_material
21102112
description: Show resource counts by category
21112113
- in: query
21122114
name: certification
@@ -2254,6 +2256,13 @@ paths:
22542256
items:
22552257
type: integer
22562258
description: The id value for the learning resource
2259+
- in: query
2260+
name: is_learning_material
2261+
schema:
2262+
type: boolean
2263+
nullable: true
2264+
description: True if the learning resource is a podcast, podcast episode,
2265+
video, video playlist, or learning path
22572266
- in: query
22582267
name: learning_format
22592268
schema:
@@ -2494,6 +2503,7 @@ paths:
24942503
- professional
24952504
- free
24962505
- learning_format
2506+
- is_learning_material
24972507
type: string
24982508
description: |-
24992509
* `resource_type` - resource_type
@@ -2508,6 +2518,7 @@ paths:
25082518
* `professional` - professional
25092519
* `free` - free
25102520
* `learning_format` - learning_format
2521+
* `is_learning_material` - is_learning_material
25112522
description: Show resource counts by category
25122523
- in: query
25132524
name: certification
@@ -2655,6 +2666,13 @@ paths:
26552666
items:
26562667
type: integer
26572668
description: The id value for the learning resource
2669+
- in: query
2670+
name: is_learning_material
2671+
schema:
2672+
type: boolean
2673+
nullable: true
2674+
description: True if the learning resource is a podcast, podcast episode,
2675+
video, video playlist, or learning path
26582676
- in: query
26592677
name: learning_format
26602678
schema:
@@ -2920,6 +2938,7 @@ paths:
29202938
- professional
29212939
- free
29222940
- learning_format
2941+
- is_learning_material
29232942
type: string
29242943
description: |-
29252944
* `resource_type` - resource_type
@@ -2934,6 +2953,7 @@ paths:
29342953
* `professional` - professional
29352954
* `free` - free
29362955
* `learning_format` - learning_format
2956+
* `is_learning_material` - is_learning_material
29372957
description: Show resource counts by category
29382958
- in: query
29392959
name: certification
@@ -3081,6 +3101,13 @@ paths:
30813101
items:
30823102
type: integer
30833103
description: The id value for the learning resource
3104+
- in: query
3105+
name: is_learning_material
3106+
schema:
3107+
type: boolean
3108+
nullable: true
3109+
description: True if the learning resource is a podcast, podcast episode,
3110+
video, video playlist, or learning path
30843111
- in: query
30853112
name: learning_format
30863113
schema:
@@ -3337,6 +3364,7 @@ paths:
33373364
- professional
33383365
- free
33393366
- learning_format
3367+
- is_learning_material
33403368
type: string
33413369
description: |-
33423370
* `resource_type` - resource_type
@@ -3351,6 +3379,7 @@ paths:
33513379
* `professional` - professional
33523380
* `free` - free
33533381
* `learning_format` - learning_format
3382+
* `is_learning_material` - is_learning_material
33543383
description: Show resource counts by category
33553384
- in: query
33563385
name: certification
@@ -3498,6 +3527,13 @@ paths:
34983527
items:
34993528
type: integer
35003529
description: The id value for the learning resource
3530+
- in: query
3531+
name: is_learning_material
3532+
schema:
3533+
type: boolean
3534+
nullable: true
3535+
description: True if the learning resource is a podcast, podcast episode,
3536+
video, video playlist, or learning path
35013537
- in: query
35023538
name: learning_format
35033539
schema:
@@ -6873,6 +6909,7 @@ components:
68736909
- professional
68746910
- free
68756911
- learning_format
6912+
- is_learning_material
68766913
type: string
68776914
description: |-
68786915
* `resource_type` - resource_type
@@ -6887,6 +6924,7 @@ components:
68876924
* `professional` - professional
68886925
* `free` - free
68896926
* `learning_format` - learning_format
6927+
* `is_learning_material` - is_learning_material
68906928
x-enum-descriptions:
68916929
- resource_type
68926930
- certification
@@ -6900,6 +6938,7 @@ components:
69006938
- professional
69016939
- free
69026940
- learning_format
6941+
- is_learning_material
69036942
Article:
69046943
type: object
69056944
description: Serializer for LearningResourceInstructor model
@@ -9218,6 +9257,11 @@ components:
92189257
type: boolean
92199258
nullable: true
92209259
description: True if the learning resource offers a certificate
9260+
is_learning_material:
9261+
type: boolean
9262+
nullable: true
9263+
description: True if the learning resource is a podcast, podcast episode,
9264+
video, video playlist, or learning path
92219265
certification_type:
92229266
type: array
92239267
items:

0 commit comments

Comments
 (0)