Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
course-discovery
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
course-discovery
Commits
e5434751
Commit
e5434751
authored
Dec 14, 2016
by
Matthew Piatetsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Boost orgs autocomplete in typeahead and add authoring organization bodies
ECOM-4738
parent
760721ad
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
53 additions
and
24 deletions
+53
-24
course_discovery/apps/api/serializers.py
+9
-15
course_discovery/apps/api/tests/test_serializers.py
+4
-4
course_discovery/apps/api/v1/tests/test_views/test_search.py
+30
-0
course_discovery/apps/course_metadata/search_indexes.py
+10
-5
No files found.
course_discovery/apps/api/serializers.py
View file @
e5434751
...
@@ -974,29 +974,23 @@ class AggregateSearchSerializer(HaystackSerializer):
...
@@ -974,29 +974,23 @@ class AggregateSearchSerializer(HaystackSerializer):
}
}
class
TypeaheadCourseRunSearchSerializer
(
serializers
.
Serializer
):
class
TypeaheadBaseSearchSerializer
(
serializers
.
Serializer
):
org
=
serializers
.
CharField
()
title
=
serializers
.
CharField
()
key
=
serializers
.
CharField
()
marketing_url
=
serializers
.
CharField
()
class
Meta
:
fields
=
[
'key'
,
'title'
]
class
TypeaheadProgramSearchSerializer
(
serializers
.
Serializer
):
orgs
=
serializers
.
SerializerMethodField
()
orgs
=
serializers
.
SerializerMethodField
()
uuid
=
serializers
.
CharField
()
title
=
serializers
.
CharField
()
title
=
serializers
.
CharField
()
type
=
serializers
.
CharField
()
marketing_url
=
serializers
.
CharField
()
marketing_url
=
serializers
.
CharField
()
def
get_orgs
(
self
,
result
):
def
get_orgs
(
self
,
result
):
authoring_organizations
=
[
json
.
loads
(
org
)
for
org
in
result
.
authoring_organization_bodies
]
authoring_organizations
=
[
json
.
loads
(
org
)
for
org
in
result
.
authoring_organization_bodies
]
return
[
org
[
'key'
]
for
org
in
authoring_organizations
]
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
):
class
TypeaheadSearchSerializer
(
serializers
.
Serializer
):
...
...
course_discovery/apps/api/tests/test_serializers.py
View file @
e5434751
...
@@ -1125,14 +1125,14 @@ class ProgramSearchSerializerTests(TestCase):
...
@@ -1125,14 +1125,14 @@ class ProgramSearchSerializerTests(TestCase):
class
TypeaheadCourseRunSearchSerializerTests
(
TestCase
):
class
TypeaheadCourseRunSearchSerializerTests
(
TestCase
):
def
test_data
(
self
):
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
)
serialized_course
=
self
.
serialize_course_run
(
course_run
)
course_run_key
=
CourseKey
.
from_string
(
course_run
.
key
)
expected
=
{
expected
=
{
'key'
:
course_run
.
key
,
'key'
:
course_run
.
key
,
'title'
:
course_run
.
title
,
'title'
:
course_run
.
title
,
'org
'
:
course_run_key
.
org
,
'org
s'
:
[
org
.
key
for
org
in
course_run
.
authoring_organizations
.
all
()]
,
'marketing_url'
:
course_run
.
marketing_url
,
'marketing_url'
:
course_run
.
marketing_url
,
}
}
self
.
assertDictEqual
(
serialized_course
.
data
,
expected
)
self
.
assertDictEqual
(
serialized_course
.
data
,
expected
)
...
@@ -1150,7 +1150,7 @@ class TypeaheadProgramSearchSerializerTests(TestCase):
...
@@ -1150,7 +1150,7 @@ class TypeaheadProgramSearchSerializerTests(TestCase):
'uuid'
:
str
(
program
.
uuid
),
'uuid'
:
str
(
program
.
uuid
),
'title'
:
program
.
title
,
'title'
:
program
.
title
,
'type'
:
program
.
type
.
name
,
'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
,
'marketing_url'
:
program
.
marketing_url
,
}
}
...
...
course_discovery/apps/api/v1/tests/test_views/test_search.py
View file @
e5434751
...
@@ -465,3 +465,33 @@ class TypeaheadSearchViewTests(TypeaheadSerializationMixin, LoginMixin, Elastics
...
@@ -465,3 +465,33 @@ class TypeaheadSearchViewTests(TypeaheadSerializationMixin, LoginMixin, Elastics
'programs'
:
[
self
.
serialize_program
(
program
)]
'programs'
:
[
self
.
serialize_program
(
program
)]
}
}
self
.
assertDictEqual
(
response
.
data
,
expected
)
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
)
course_discovery/apps/course_metadata/search_indexes.py
View file @
e5434751
...
@@ -14,6 +14,10 @@ from course_discovery.apps.course_metadata.models import Course, CourseRun, Prog
...
@@ -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
# If we altered our boosting functions to have a max score of 10
# we would probably want to bump this number.
# we would probably want to bump this number.
TITLE_FIELD_BOOST
=
25.0
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
:
class
OrganizationsMixin
:
...
@@ -30,6 +34,9 @@ class OrganizationsMixin:
...
@@ -30,6 +34,9 @@ class OrganizationsMixin:
def
_prepare_organizations
(
self
,
organizations
):
def
_prepare_organizations
(
self
,
organizations
):
return
[
self
.
format_organization
(
organization
)
for
organization
in
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
):
def
prepare_authoring_organizations
(
self
,
obj
):
return
self
.
_prepare_organizations
(
obj
.
authoring_organizations
.
all
())
return
self
.
_prepare_organizations
(
obj
.
authoring_organizations
.
all
())
...
@@ -63,7 +70,8 @@ class BaseCourseIndex(OrganizationsMixin, BaseIndex):
...
@@ -63,7 +70,8 @@ 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
()
authoring_organizations_autocomplete
=
indexes
.
NgramField
(
boost
=
ORG_FIELD_BOOST
)
authoring_organization_bodies
=
indexes
.
MultiValueField
()
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
)
...
@@ -197,7 +205,7 @@ class ProgramIndex(BaseIndex, indexes.Indexable, OrganizationsMixin):
...
@@ -197,7 +205,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_organizations_autocomplete
=
indexes
.
NgramField
(
boost
=
ORG_FIELD_BOOST
)
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
()
...
@@ -216,9 +224,6 @@ class ProgramIndex(BaseIndex, indexes.Indexable, OrganizationsMixin):
...
@@ -216,9 +224,6 @@ class ProgramIndex(BaseIndex, indexes.Indexable, OrganizationsMixin):
def
prepare_organizations
(
self
,
obj
):
def
prepare_organizations
(
self
,
obj
):
return
self
.
prepare_authoring_organizations
(
obj
)
+
self
.
prepare_credit_backing_organizations
(
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
):
def
prepare_subject_uuids
(
self
,
obj
):
return
[
str
(
subject
.
uuid
)
for
course
in
obj
.
courses
.
all
()
for
subject
in
course
.
subjects
.
all
()]
return
[
str
(
subject
.
uuid
)
for
course
in
obj
.
courses
.
all
()
for
subject
in
course
.
subjects
.
all
()]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment