Commit d6b515a1 by Matthew Piatetsky

Add orgs autocomplete to typeahead

ECOM-4738
parent c9c077bc
...@@ -432,3 +432,18 @@ class TypeaheadSearchViewTests(TypeaheadSerializationMixin, LoginMixin, Elastics ...@@ -432,3 +432,18 @@ class TypeaheadSearchViewTests(TypeaheadSerializationMixin, LoginMixin, Elastics
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
response_data = response.json() response_data = response.json()
self.assertEqual(response_data['course_runs'][0]['title'], title + "2") self.assertEqual(response_data['course_runs'][0]['title'], title + "2")
def test_typeahead_authoring_organizations_partial_search(self):
""" Test typeahead response with partial organization matching. """
authoring_organizations = OrganizationFactory.create_batch(3)
course_run = CourseRunFactory(authoring_organizations=authoring_organizations)
program = ProgramFactory(authoring_organizations=authoring_organizations)
partial_key = authoring_organizations[0].key[0:5]
response = self.get_typeahead_response(partial_key)
self.assertEqual(response.status_code, 200)
expected = {
'course_runs': [self.serialize_course_run(course_run)],
'programs': [self.serialize_program(program)]
}
self.assertDictEqual(response.data, expected)
...@@ -126,12 +126,24 @@ class TypeaheadSearchView(APIView): ...@@ -126,12 +126,24 @@ class TypeaheadSearchView(APIView):
permission_classes = (IsAuthenticated,) permission_classes = (IsAuthenticated,)
def get_results(self, query): def get_results(self, query):
course_runs = SearchQuerySet().models(CourseRun).filter(SQ(title_autocomplete=query) | SQ(course_key=query)) sqs = SearchQuerySet()
clean_query = sqs.query.clean(query)
course_runs = sqs.models(CourseRun).filter(
SQ(title_autocomplete=clean_query) |
SQ(course_key=clean_query) |
SQ(authoring_organizations_autocomplete=clean_query)
)
course_runs = course_runs.filter(published=True).exclude(hidden=True) course_runs = course_runs.filter(published=True).exclude(hidden=True)
course_runs = course_runs[:self.RESULT_COUNT] course_runs = course_runs[:self.RESULT_COUNT]
programs = SearchQuerySet().models(Program).filter(SQ(title_autocomplete=query))
programs = sqs.models(Program).filter(
SQ(title_autocomplete=clean_query) |
SQ(authoring_organizations_autocomplete=clean_query)
)
programs = programs.filter(status=ProgramStatus.Active) programs = programs.filter(status=ProgramStatus.Active)
programs = programs[:self.RESULT_COUNT] programs = programs[:self.RESULT_COUNT]
return course_runs, programs return course_runs, programs
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
......
...@@ -33,6 +33,9 @@ class OrganizationsMixin: ...@@ -33,6 +33,9 @@ class OrganizationsMixin:
def prepare_authoring_organizations(self, obj): def prepare_authoring_organizations(self, obj):
return self._prepare_organizations(obj.authoring_organizations.all()) return self._prepare_organizations(obj.authoring_organizations.all())
def prepare_authoring_organizations_autocomplete(self, obj):
return self.prepare_authoring_organizations(obj)
class BaseIndex(indexes.SearchIndex): class BaseIndex(indexes.SearchIndex):
model = None model = None
...@@ -60,6 +63,7 @@ class BaseCourseIndex(OrganizationsMixin, BaseIndex): ...@@ -60,6 +63,7 @@ class BaseCourseIndex(OrganizationsMixin, BaseIndex):
key = indexes.CharField(model_attr='key', stored=True) key = indexes.CharField(model_attr='key', stored=True)
title = indexes.CharField(model_attr='title', boost=TITLE_FIELD_BOOST) title = indexes.CharField(model_attr='title', boost=TITLE_FIELD_BOOST)
title_autocomplete = indexes.NgramField(model_attr='title', boost=TITLE_FIELD_BOOST) title_autocomplete = indexes.NgramField(model_attr='title', boost=TITLE_FIELD_BOOST)
authoring_organizations_autocomplete = indexes.NgramField()
short_description = indexes.CharField(model_attr='short_description', null=True) short_description = indexes.CharField(model_attr='short_description', null=True)
full_description = indexes.CharField(model_attr='full_description', null=True) full_description = indexes.CharField(model_attr='full_description', null=True)
subjects = indexes.MultiValueField(faceted=True) subjects = indexes.MultiValueField(faceted=True)
...@@ -193,6 +197,7 @@ class ProgramIndex(BaseIndex, indexes.Indexable, OrganizationsMixin): ...@@ -193,6 +197,7 @@ class ProgramIndex(BaseIndex, indexes.Indexable, OrganizationsMixin):
marketing_url = indexes.CharField(null=True) marketing_url = indexes.CharField(null=True)
organizations = indexes.MultiValueField(faceted=True) organizations = indexes.MultiValueField(faceted=True)
authoring_organizations = indexes.MultiValueField(faceted=True) authoring_organizations = indexes.MultiValueField(faceted=True)
authoring_organizations_autocomplete = indexes.NgramField()
authoring_organization_uuids = indexes.MultiValueField() authoring_organization_uuids = indexes.MultiValueField()
subject_uuids = indexes.MultiValueField() subject_uuids = indexes.MultiValueField()
staff_uuids = indexes.MultiValueField() staff_uuids = indexes.MultiValueField()
......
...@@ -99,6 +99,8 @@ class ConfigurableElasticBackend(ElasticsearchSearchBackend): ...@@ -99,6 +99,8 @@ class ConfigurableElasticBackend(ElasticsearchSearchBackend):
# and all words containing ing would come back in typeahead. # and all words containing ing would come back in typeahead.
self.specify_analyzers(mapping=mapping, field='title_autocomplete', self.specify_analyzers(mapping=mapping, field='title_autocomplete',
index_analyzer='ngram_analyzer', search_analyzer='lowercase') index_analyzer='ngram_analyzer', search_analyzer='lowercase')
self.specify_analyzers(mapping=mapping, field='authoring_organizations_autocomplete',
index_analyzer='ngram_analyzer', search_analyzer='lowercase')
return (content_field_name, mapping) return (content_field_name, mapping)
......
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