Use Opensearch for learning resource API results whenever feasible
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 3
- Forks
- 4
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 114
Description
Description/Context
Use opensearch for API results for lists when feasible (ie not for lists of learning paths requested by editors, perhaps other exceptions) and perhaps single object results as well.
Plan/Design
Option 1: OpenSearch endpoint for lists, database endpoints for individual objects and learning path CRUD
Continue using the database to return:
- Published individual learning resource details (url:
/api/v1/learning_resources/<pk>/,/api/v1/courses/<pk>/, etc) - Published child resources of a resource (url:
/api/v1/learning_resources/<pk>/children/). Example: episodes in a podcast, resources in a learning path
Provide a new database-backed API endpoint - /api/v1/learning_path_admin/ - specifically for learning paths CRUD. This will return specific path details as well as lists of learning paths, both published and unpublished. Only users with editing permission will be allowed to access it.
Use opensearch for all read-only learning resource list endpoints (published only):
/api/v1/learning_resources/,/api/v1/courses/,/api/v1/programs/, etc/api/v1/learning_resources/new/(need to addcreated_onvalues to the index and sort by that)api/v1/learning_resources/upcoming/(need to build an opensearch query filtering byruns.publishedand (runs.start_dateorruns.enrollment_start) then ordering byruns.start_date)
Separate views will be used for each:
learning_resources.views.LearningResourceViewSet(RetrieveModelMixin, viewsets.GenericViewSet)for individual objects and their childrenlearning_resources.views.LearningPathAdminViewSet(viewsets.ModelViewSet)for learning path CRUDlearning_resources_search.views.LearningResourcesSearchView(ESView)for lists of learning resources.
URL's would have to be loaded in the following order in open_discussions/urls.py:
re_path(r"", include("learning_resources.urls")),
re_path(r"", include("learning_resources_search.urls")),
Option 2: OpenSearch endpoint for lists and individual results, database for learning path editing only.
Similar to above, but use opensearch for individual object results and child resources of individual results
- Would need to adjust serializers so that each child resource document in opensearch includes a
parentsfield indicating the relation (and type of relation) to other resources. For example,/api/v1/podcasts/<id>/episodescould not rely on database relationships to get correct results, would need to query opensearch whereparent_id=<id>andrelation_type=podcast,
Separate views will be used for each:
learning_resources.views.LearningPathViewSet(viewsets.ModelViewSet)for learning path CRUDlearning_resources_search.views.LearningResourcesSearchView(ESView)for learning resources lists and individual objects
Option 3: Conditionally switch to an opensearch API view from a database API view, depending on parameters.
@extend_schema(responses=LearningResourceSerializer(many=True))
@action(methods=["GET"], detail=False, name="New Resources")
def new(self, request: Request) -> QuerySet: # noqa: ARG002
if self.use_database(): # query param of db=True, or path editor requesting list of all paths
page = self.paginate_queryset(self.get_queryset().order_by("-created_on"))
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
return LearningResourcesSearchView().get(request, sortby="-created_on")
# or insert the code from the view above here directly.
This does not seem like the best approach, for several reasons:
-
It mixes views from two different apps, which does not seem like good practice
-
Need to ensure that the different views always accept the same query parameters and apply filters consistently.
-
The views may have slightly different outputs. For example, the current search endpoint does not include
nextandpreviouspage attributes, though maybe it should. And the current database-backed endpoint never includes this data structure:"metadata": { "aggregations": {}, "suggest": [] }Though again, the outputs could probably be made consistent, up to a point (if using database, can't get actual values for those metadata fields, other than empty ones like above).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by comparing the existing endpoints in learning_resources.views, learning_resources_search.views, their URLs, and open_discussions/urls.py. Review the three proposed options and the current search response and filters before choosing an approach. Done means the selected published list endpoints use OpenSearch while learning path editing and any documented database-backed exceptions continue to work consistently.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend, search
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100