Commit a4428909 by Matthew Piatetsky Committed by GitHub

Merge pull request #490 from edx/boost_orgs_typeahead

Boost orgs autocomplete in typeahead
parents 760721ad e5434751
......@@ -974,29 +974,23 @@ class AggregateSearchSerializer(HaystackSerializer):
}
class TypeaheadCourseRunSearchSerializer(serializers.Serializer):
org = serializers.CharField()
title = serializers.CharField()
key = serializers.CharField()
marketing_url = serializers.CharField()
class Meta:
fields = ['key', 'title']
class TypeaheadProgramSearchSerializer(serializers.Serializer):
class TypeaheadBaseSearchSerializer(serializers.Serializer):
orgs = serializers.SerializerMethodField()
uuid = serializers.CharField()
title = serializers.CharField()
type = serializers.CharField()
marketing_url = serializers.CharField()
def get_orgs(self, result):
authoring_organizations = [json.loads(org) for org in result.authoring_organization_bodies]
return [org['key'] for org in authoring_organizations]
class Meta:
fields = ['uuid', 'title', 'type']
class TypeaheadCourseRunSearchSerializer(TypeaheadBaseSearchSerializer):
key = serializers.CharField()
class TypeaheadProgramSearchSerializer(TypeaheadBaseSearchSerializer):
uuid = serializers.CharField()
type = serializers.CharField()
class TypeaheadSearchSerializer(serializers.Serializer):
......
......@@ -1125,14 +1125,14 @@ class ProgramSearchSerializerTests(TestCase):
class TypeaheadCourseRunSearchSerializerTests(TestCase):
def test_data(self):
course_run = CourseRunFactory()
authoring_organization = OrganizationFactory()
course_run = CourseRunFactory(authoring_organizations=[authoring_organization])
serialized_course = self.serialize_course_run(course_run)
course_run_key = CourseKey.from_string(course_run.key)
expected = {
'key': course_run.key,
'title': course_run.title,
'org': course_run_key.org,
'orgs': [org.key for org in course_run.authoring_organizations.all()],
'marketing_url': course_run.marketing_url,
}
self.assertDictEqual(serialized_course.data, expected)
......@@ -1150,7 +1150,7 @@ class TypeaheadProgramSearchSerializerTests(TestCase):
'uuid': str(program.uuid),
'title': program.title,
'type': program.type.name,
'orgs': list(program.authoring_organizations.all().values_list('key', flat=True)),
'orgs': [org.key for org in program.authoring_organizations.all()],
'marketing_url': program.marketing_url,
}
......
......@@ -465,3 +465,33 @@ class TypeaheadSearchViewTests(TypeaheadSerializationMixin, LoginMixin, Elastics
'programs': [self.serialize_program(program)]
}
self.assertDictEqual(response.data, expected)
def test_typeahead_org_course_runs_come_up_first(self):
""" Test typeahead response to ensure org is taken into account. """
MITx = OrganizationFactory(key='MITx')
HarvardX = OrganizationFactory(key='HarvardX')
mit_run = CourseRunFactory(
authoring_organizations=[MITx, HarvardX],
title='MIT Testing1'
)
harvard_run = CourseRunFactory(
authoring_organizations=[HarvardX],
title='MIT Testing2'
)
mit_program = ProgramFactory(
authoring_organizations=[MITx, HarvardX],
title='MIT Testing1'
)
harvard_program = ProgramFactory(
authoring_organizations=[HarvardX],
title='MIT Testing2'
)
response = self.get_typeahead_response('mit')
self.assertEqual(response.status_code, 200)
expected = {
'course_runs': [self.serialize_course_run(mit_run),
self.serialize_course_run(harvard_run)],
'programs': [self.serialize_program(mit_program),
self.serialize_program(harvard_program)]
}
self.assertDictEqual(response.data, expected)
......@@ -14,6 +14,10 @@ from course_discovery.apps.course_metadata.models import Course, CourseRun, Prog
# If we altered our boosting functions to have a max score of 10
# we would probably want to bump this number.
TITLE_FIELD_BOOST = 25.0
# We want to boost org the same as title
# Primarily this is to prevent courses from other institutions
# coming up first if there is a partial match on title
ORG_FIELD_BOOST = TITLE_FIELD_BOOST
class OrganizationsMixin:
......@@ -30,6 +34,9 @@ class OrganizationsMixin:
def _prepare_organizations(self, organizations):
return [self.format_organization(organization) for organization in organizations]
def prepare_authoring_organization_bodies(self, obj):
return [self.format_organization_body(organization) for organization in obj.authoring_organizations.all()]
def prepare_authoring_organizations(self, obj):
return self._prepare_organizations(obj.authoring_organizations.all())
......@@ -63,7 +70,8 @@ class BaseCourseIndex(OrganizationsMixin, BaseIndex):
key = indexes.CharField(model_attr='key', stored=True)
title = indexes.CharField(model_attr='title', boost=TITLE_FIELD_BOOST)
title_autocomplete = indexes.NgramField(model_attr='title', boost=TITLE_FIELD_BOOST)
authoring_organizations_autocomplete = indexes.NgramField()
authoring_organizations_autocomplete = indexes.NgramField(boost=ORG_FIELD_BOOST)
authoring_organization_bodies = indexes.MultiValueField()
short_description = indexes.CharField(model_attr='short_description', null=True)
full_description = indexes.CharField(model_attr='full_description', null=True)
subjects = indexes.MultiValueField(faceted=True)
......@@ -197,7 +205,7 @@ class ProgramIndex(BaseIndex, indexes.Indexable, OrganizationsMixin):
marketing_url = indexes.CharField(null=True)
organizations = indexes.MultiValueField(faceted=True)
authoring_organizations = indexes.MultiValueField(faceted=True)
authoring_organizations_autocomplete = indexes.NgramField()
authoring_organizations_autocomplete = indexes.NgramField(boost=ORG_FIELD_BOOST)
authoring_organization_uuids = indexes.MultiValueField()
subject_uuids = indexes.MultiValueField()
staff_uuids = indexes.MultiValueField()
......@@ -216,9 +224,6 @@ class ProgramIndex(BaseIndex, indexes.Indexable, OrganizationsMixin):
def prepare_organizations(self, obj):
return self.prepare_authoring_organizations(obj) + self.prepare_credit_backing_organizations(obj)
def prepare_authoring_organization_bodies(self, obj):
return [self.format_organization_body(organization) for organization in obj.authoring_organizations.all()]
def prepare_subject_uuids(self, obj):
return [str(subject.uuid) for course in obj.courses.all() for subject in course.subjects.all()]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment