Search : Facets with subject

Hello everyone !
We have a running openedx on Kubernetes, and we would like to expand the search function.
We tried this :

        "COURSE_DISCOVERY_FILTERS" : [
            "subjects",
            "org",
            "language",
            "modes"
          ]

When we perform a search the result from Ajax call to /search/course_discovery/ is the following :

    facets: {org: {other: 0, total: 5, terms: {XXX-: 2, XXX: 1, XXX: 2}},…}
    language: {other: 0, total: 5, terms: {en: 2, fr: 3}}
    modes: {other: 0, total: 5, terms: {audit: 5}}
    org: {other: 0, total: 5, terms: {XXX-: 2, XXX: 1, XXX: 2}}
    subjects: {other: 0, total: 0, terms: {}}

The “subjects” object is empty, but we can’t find anything on Studio where to put the course subject ! Following this link to edx docs there are some guidelines for subject.

Any tips on how to enable the subjects ?

Thanks !

The search facets you see in edx.org are implemented for their marketing site (edx-mktg, drupal-based) which is private to edx.org.

edx-platform code base does not implement subjects field in the first place. You can still find subjects in discovery's models since it aggregaes data from several sources (marketing site included).

Without the private edx.org marketing site, there is no ready to use solution.

All I can tell you is how we at steps we at FennecTech could implement custom search facets (though we’d prefer having a marketing site to reduce unnecessary load on the edxapp servers).

  1. Have a way to add subjects to your course metadata. You can do that in 2 ways:
    a. Enable other course settings feature flag, then add a subjects field to each of your courses in CMS > Your course > Advanced Settings > Other Course Settings
    b. Hard-code a subjects field for the course. If you do so, you need to provide a way to edit your field either in the “Advanced Settings” or “Schedule & Details” of the course.
  2. Add your field to the courseware index: Your field needs to be indexed first by ElasticSearch before you’ll be able to get non-zero results.
  3. Do your COURSE_DISCOVERY_FILTERS modifications exactly as you did.
  4. Reindex all courses either from Studio’s interface or using the django command ./manage.py cms reindex_course --all

If you need to show subjecs in other places such as course cards or the course about page, you’ll have to integrate them yourself.

Here’s a demo on how it looks like
https://fennecacademy.tk/courses

If you still further assistane with this feature implementation, feel free to contact us. We’d be glad to provide you the support you need.

Hello,
Thanks @ARMBouhali for your answer.
We already started working with “other course settings” and added a “subject” to some courses. We managed to show the field on the course.html using course.other_course_settings.get(‘subject’), but can’t find exactly how to return that field via course API.
Can you explain further how to get ElasticSearch to index the field and return it ?
Thanks !

Open edX uses edx-search package which uses ElasticSearch vy default.

Tip : you have to edit cms/djangoapps/contentstore/courseware_index.py where the search indexer is defined. All your edits should be in that file. You’ll find there all the fields that are indexed. Use that as an example to index your custom field. Create a new callback FROM_OTHER_SETTINGS to handle the parsing of your subjects, then use it as an argument in the ABOUT_INFO definitions.

To test,your code, you need to reindex_course each time then query ElasticSearch at `http://localhost:9200/courseware_index/_search?pretty=true&size=10000&type=course_info.

Note that object values that evaluate to False (0, [], {}, None) are not indexed (as if they didn’t exist)

2 Likes

Hello again,
Thanks for the tip ! Got it to work.
For further reference, if anyone needs it, here are the steps (the example is for adding a “subject”) :
1- First, you need to add a field under “other course settings” in course’s advanced settings in Studio
2- As suggested by @ARMBouhali make the following changes to cms/djangoapps/contentstore/courseware_index.py :
add to class AboutInfo

def from_other_settings(self, **kwargs):
        course = kwargs.get('course', None)
        if not course:
            raise ValueError("Context dictionary does not contain expected argument 'course' ")
        return course.other_course_settings.get('subject')

FROM_OTHER_SETTINGS = from_other_settings

3- Under ABOUT_INFORMATION_TO_INCLUDE add the following :

AboutInfo("subject", AboutInfo.PROPERTY, AboutInfo.FROM_OTHER_SETTINGS),

4- Add to LMS config :

"COURSE_DISCOVERY_FILTERS" : [
            "subject",
            "org",
            "language",
            "modes"
          ]

You will now have a filter named “subject”
Don’t forget to reindex your course !

An out of context question, @ARMBouhali , is there a way to have by default { "subject": "" } on advanced settings for new courses ? so that course creators can easily populate it and avoid any typo errors ?

3 Likes

@Ahmed_Bennani Glad it worked for you.

You can handle a default subject value by setting the default value of the CourseFields.other_settings (look for the class name). This way, all new created courses will use that default value.
However, if you have to edit the CourseFields class, rather add a custom subjects field instead,

Back to my first answer:

  1. b. Hard-code a subjects field for the course. If you do so, you need to provide a way to edit your field either in the “Advanced Settings” or “Schedule & Details” of the course.
1 Like

Thanks again !
I’ll look into that after, actually changing templates to show the subject on course cards.
I’ll keep you posted.

1 Like

@Ahmed_Bennani do you need to run any sort of migrations to have the fields in “other course settings” be accessible in the mako/django templates? I keep an error message:

AttributeError: ‘CourseOverview’ object has no attribute ‘other_course_settings’

when I try to access a custom field called “course_language” in the course.html template like so:

<%
course_language = course.other_course_settings.get(‘course_language’)
%>

10000000 thanks!!! it work for me… again thanks