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
a4428909
Commit
a4428909
authored
Dec 15, 2016
by
Matthew Piatetsky
Committed by
GitHub
Dec 15, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #490 from edx/boost_orgs_typeahead
Boost orgs autocomplete in typeahead
parents
760721ad
e5434751
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 @
a4428909
...
@@ -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 @
a4428909
...
@@ -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 @
a4428909
...
@@ -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 @
a4428909
...
@@ -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