Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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
edx-platform
Commits
3bd76f98
Commit
3bd76f98
authored
Dec 10, 2013
by
Don Mitchell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use mongo indices for all queries
STUD-1039
parent
f4beb8b8
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
72 additions
and
26 deletions
+72
-26
cms/djangoapps/contentstore/views/course.py
+2
-1
common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py
+44
-20
common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py
+5
-5
mongo_indexes.md
+21
-0
No files found.
cms/djangoapps/contentstore/views/course.py
View file @
3bd76f98
...
@@ -128,7 +128,8 @@ def course_listing(request):
...
@@ -128,7 +128,8 @@ def course_listing(request):
"""
"""
List all courses available to the logged in user
List all courses available to the logged in user
"""
"""
courses
=
modulestore
(
'direct'
)
.
get_items
(
Location
(
'i4x'
,
None
,
None
,
'course'
,
None
))
# there's an index on category which will be used if none of its antecedents are set
courses
=
modulestore
(
'direct'
)
.
get_items
(
Location
(
None
,
None
,
None
,
'course'
,
None
))
# filter out courses that we don't have access too
# filter out courses that we don't have access too
def
course_filter
(
course
):
def
course_filter
(
course
):
...
...
common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py
View file @
3bd76f98
...
@@ -4,10 +4,10 @@ Method for converting among our differing Location/Locator whatever reprs
...
@@ -4,10 +4,10 @@ Method for converting among our differing Location/Locator whatever reprs
from
random
import
randint
from
random
import
randint
import
re
import
re
import
pymongo
import
pymongo
import
bson.son
from
xmodule.modulestore.exceptions
import
InvalidLocationError
,
ItemNotFoundError
,
DuplicateItemError
from
xmodule.modulestore.exceptions
import
InvalidLocationError
,
ItemNotFoundError
,
DuplicateItemError
from
xmodule.modulestore.locator
import
BlockUsageLocator
from
xmodule.modulestore.locator
import
BlockUsageLocator
from
xmodule.modulestore.mongo
import
draft
from
xmodule.modulestore
import
Location
from
xmodule.modulestore
import
Location
import
urllib
import
urllib
...
@@ -91,9 +91,10 @@ class LocMapperStore(object):
...
@@ -91,9 +91,10 @@ class LocMapperStore(object):
else
:
else
:
course_id
=
"{0.org}.{0.course}"
.
format
(
course_location
)
course_id
=
"{0.org}.{0.course}"
.
format
(
course_location
)
# very like _interpret_location_id but w/o the _id
# very like _interpret_location_id but w/o the _id
location_id
=
{
'org'
:
course_location
.
org
,
'course'
:
course_location
.
course
}
location_id
=
self
.
_construct_location_son
(
if
course_location
.
category
==
'course'
:
course_location
.
org
,
course_location
.
course
,
location_id
[
'name'
]
=
course_location
.
name
course_location
.
name
if
course_location
.
category
==
'course'
else
None
)
self
.
location_map
.
insert
({
self
.
location_map
.
insert
({
'_id'
:
location_id
,
'_id'
:
location_id
,
...
@@ -128,20 +129,25 @@ class LocMapperStore(object):
...
@@ -128,20 +129,25 @@ class LocMapperStore(object):
"""
"""
location_id
=
self
.
_interpret_location_course_id
(
old_style_course_id
,
location
)
location_id
=
self
.
_interpret_location_course_id
(
old_style_course_id
,
location
)
maps
=
self
.
location_map
.
find
(
location_id
)
.
sort
(
'_id.name'
,
pymongo
.
ASCENDING
)
maps
=
self
.
location_map
.
find
(
location_id
)
if
maps
.
count
()
==
0
:
maps
=
list
(
maps
)
if
len
(
maps
)
==
0
:
if
add_entry_if_missing
:
if
add_entry_if_missing
:
# create a new map
# create a new map
course_location
=
location
.
replace
(
category
=
'course'
,
name
=
location_id
[
'_id
.
name'
])
course_location
=
location
.
replace
(
category
=
'course'
,
name
=
location_id
[
'_id
'
][
'
name'
])
self
.
create_map_entry
(
course_location
)
self
.
create_map_entry
(
course_location
)
entry
=
self
.
location_map
.
find_one
(
location_id
)
entry
=
self
.
location_map
.
find_one
(
location_id
)
else
:
else
:
raise
ItemNotFoundError
()
raise
ItemNotFoundError
()
elif
maps
.
count
()
>
1
:
elif
len
(
maps
)
==
1
:
# if more than one, prefer the one w/o a name if that exists. Otherwise, choose the first (alphabetically)
entry
=
maps
[
0
]
entry
=
maps
[
0
]
else
:
else
:
# find entry w/o name, if any; otherwise, pick arbitrary
entry
=
maps
[
0
]
entry
=
maps
[
0
]
for
item
in
maps
:
if
'name'
not
in
item
[
'_id'
]:
entry
=
item
break
if
published
:
if
published
:
branch
=
entry
[
'prod_branch'
]
branch
=
entry
[
'prod_branch'
]
...
@@ -242,11 +248,11 @@ class LocMapperStore(object):
...
@@ -242,11 +248,11 @@ class LocMapperStore(object):
location_id
=
self
.
_interpret_location_course_id
(
old_course_id
,
location
)
location_id
=
self
.
_interpret_location_course_id
(
old_course_id
,
location
)
maps
=
self
.
location_map
.
find
(
location_id
)
maps
=
self
.
location_map
.
find
(
location_id
)
if
maps
.
count
()
==
0
:
raise
ItemNotFoundError
()
# turn maps from cursor to list
# turn maps from cursor to list
map_list
=
list
(
maps
)
map_list
=
list
(
maps
)
if
len
(
map_list
)
==
0
:
raise
ItemNotFoundError
()
encoded_location_name
=
self
.
_encode_for_mongo
(
location
.
name
)
encoded_location_name
=
self
.
_encode_for_mongo
(
location
.
name
)
# check whether there's already a usage_id for this location (and it agrees w/ any passed in or found)
# check whether there's already a usage_id for this location (and it agrees w/ any passed in or found)
for
map_entry
in
map_list
:
for
map_entry
in
map_list
:
...
@@ -279,7 +285,10 @@ class LocMapperStore(object):
...
@@ -279,7 +285,10 @@ class LocMapperStore(object):
)
)
map_entry
[
'block_map'
]
.
setdefault
(
encoded_location_name
,
{})[
location
.
category
]
=
computed_usage_id
map_entry
[
'block_map'
]
.
setdefault
(
encoded_location_name
,
{})[
location
.
category
]
=
computed_usage_id
self
.
location_map
.
update
({
'_id'
:
map_entry
[
'_id'
]},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}})
self
.
location_map
.
update
(
{
'_id'
:
self
.
_construct_location_son
(
**
map_entry
[
'_id'
])},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}}
)
return
computed_usage_id
return
computed_usage_id
...
@@ -317,7 +326,10 @@ class LocMapperStore(object):
...
@@ -317,7 +326,10 @@ class LocMapperStore(object):
if
location
.
category
in
map_entry
[
'block_map'
]
.
setdefault
(
encoded_location_name
,
{}):
if
location
.
category
in
map_entry
[
'block_map'
]
.
setdefault
(
encoded_location_name
,
{}):
map_entry
[
'block_map'
][
encoded_location_name
][
location
.
category
]
=
usage_id
map_entry
[
'block_map'
][
encoded_location_name
][
location
.
category
]
=
usage_id
self
.
location_map
.
update
({
'_id'
:
map_entry
[
'_id'
]},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}})
self
.
location_map
.
update
(
{
'_id'
:
self
.
_construct_location_son
(
**
map_entry
[
'_id'
])},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}}
)
return
usage_id
return
usage_id
...
@@ -338,7 +350,10 @@ class LocMapperStore(object):
...
@@ -338,7 +350,10 @@ class LocMapperStore(object):
del
map_entry
[
'block_map'
][
encoded_location_name
]
del
map_entry
[
'block_map'
][
encoded_location_name
]
else
:
else
:
del
map_entry
[
'block_map'
][
encoded_location_name
][
location
.
category
]
del
map_entry
[
'block_map'
][
encoded_location_name
][
location
.
category
]
self
.
location_map
.
update
({
'_id'
:
map_entry
[
'_id'
]},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}})
self
.
location_map
.
update
(
{
'_id'
:
self
.
_construct_location_son
(
**
map_entry
[
'_id'
])},
{
'$set'
:
{
'block_map'
:
map_entry
[
'block_map'
]}}
)
def
_add_to_block_map
(
self
,
location
,
location_id
,
block_map
):
def
_add_to_block_map
(
self
,
location
,
location_id
,
block_map
):
'''add the given location to the block_map and persist it'''
'''add the given location to the block_map and persist it'''
...
@@ -357,7 +372,7 @@ class LocMapperStore(object):
...
@@ -357,7 +372,7 @@ class LocMapperStore(object):
def
_interpret_location_course_id
(
self
,
course_id
,
location
):
def
_interpret_location_course_id
(
self
,
course_id
,
location
):
"""
"""
Take the old style course id (org/course/run) and return a dict for querying the mapping table.
Take the old style course id (org/course/run) and return a dict
w/ a SON
for querying the mapping table.
If the course_id is empty, it uses location, but this may result in an inadequate id.
If the course_id is empty, it uses location, but this may result in an inadequate id.
:param course_id: old style 'org/course/run' id from Location.course_id where Location.category = 'course'
:param course_id: old style 'org/course/run' id from Location.course_id where Location.category = 'course'
...
@@ -367,12 +382,21 @@ class LocMapperStore(object):
...
@@ -367,12 +382,21 @@ class LocMapperStore(object):
if
course_id
:
if
course_id
:
# re doesn't allow ?P<_id.org> and ilk
# re doesn't allow ?P<_id.org> and ilk
matched
=
re
.
match
(
r'([^/]+)/([^/]+)/([^/]+)'
,
course_id
)
matched
=
re
.
match
(
r'([^/]+)/([^/]+)/([^/]+)'
,
course_id
)
return
dict
(
zip
([
'_id.org'
,
'_id.course'
,
'_id.name'
],
matched
.
groups
()))
return
{
'_id'
:
self
.
_construct_location_son
(
*
matched
.
groups
())}
location_id
=
{
'_id.org'
:
location
.
org
,
'_id.course'
:
location
.
course
}
if
location
.
category
==
'course'
:
if
location
.
category
==
'course'
:
location_id
[
'_id.name'
]
=
location
.
name
return
{
'_id'
:
self
.
_construct_location_son
(
location
.
org
,
location
.
course
,
location
.
name
)}
return
location_id
else
:
return
bson
.
son
.
SON
([(
'_id.org'
,
location
.
org
),
(
'_id.course'
,
location
.
course
)])
def
_construct_location_son
(
self
,
org
,
course
,
name
=
None
):
"""
Construct the SON needed to repr the location for either a query or an insertion
"""
if
name
:
return
bson
.
son
.
SON
([(
'org'
,
org
),
(
'course'
,
course
),
(
'name'
,
name
)])
else
:
return
bson
.
son
.
SON
([(
'org'
,
org
),
(
'course'
,
course
)])
def
_block_id_is_guid
(
self
,
name
):
def
_block_id_is_guid
(
self
,
name
):
"""
"""
...
...
common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py
View file @
3bd76f98
...
@@ -36,8 +36,9 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -36,8 +36,9 @@ class TestLocationMapper(unittest.TestCase):
org
=
'foo_org'
org
=
'foo_org'
course
=
'bar_course'
course
=
'bar_course'
loc_mapper
()
.
create_map_entry
(
Location
(
'i4x'
,
org
,
course
,
'course'
,
'baz_run'
))
loc_mapper
()
.
create_map_entry
(
Location
(
'i4x'
,
org
,
course
,
'course'
,
'baz_run'
))
# pylint: disable=protected-access
entry
=
loc_mapper
()
.
location_map
.
find_one
({
entry
=
loc_mapper
()
.
location_map
.
find_one
({
'_id'
:
{
'org'
:
org
,
'course'
:
course
,
'name'
:
'baz_run'
}
'_id'
:
loc_mapper
()
.
_construct_location_son
(
org
,
course
,
'baz_run'
)
})
})
self
.
assertIsNotNone
(
entry
,
"Didn't find entry"
)
self
.
assertIsNotNone
(
entry
,
"Didn't find entry"
)
self
.
assertEqual
(
entry
[
'course_id'
],
'{}.{}.baz_run'
.
format
(
org
,
course
))
self
.
assertEqual
(
entry
[
'course_id'
],
'{}.{}.baz_run'
.
format
(
org
,
course
))
...
@@ -48,8 +49,9 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -48,8 +49,9 @@ class TestLocationMapper(unittest.TestCase):
# ensure create_entry does the right thing when not given a course (creates org/course
# ensure create_entry does the right thing when not given a course (creates org/course
# rather than org/course/run course_id)
# rather than org/course/run course_id)
loc_mapper
()
.
create_map_entry
(
Location
(
'i4x'
,
org
,
course
,
'vertical'
,
'baz_vert'
))
loc_mapper
()
.
create_map_entry
(
Location
(
'i4x'
,
org
,
course
,
'vertical'
,
'baz_vert'
))
# find the one which has no name
entry
=
loc_mapper
()
.
location_map
.
find_one
({
entry
=
loc_mapper
()
.
location_map
.
find_one
({
'_id'
:
{
'org'
:
org
,
'course'
:
course
}
'_id'
:
loc_mapper
()
.
_construct_location_son
(
org
,
course
,
None
)
})
})
self
.
assertIsNotNone
(
entry
,
"Didn't find entry"
)
self
.
assertIsNotNone
(
entry
,
"Didn't find entry"
)
self
.
assertEqual
(
entry
[
'course_id'
],
'{}.{}'
.
format
(
org
,
course
))
self
.
assertEqual
(
entry
[
'course_id'
],
'{}.{}'
.
format
(
org
,
course
))
...
@@ -63,9 +65,7 @@ class TestLocationMapper(unittest.TestCase):
...
@@ -63,9 +65,7 @@ class TestLocationMapper(unittest.TestCase):
'wip'
,
'wip'
,
'live'
,
'live'
,
block_map
)
block_map
)
entry
=
loc_mapper
()
.
location_map
.
find_one
({
entry
=
loc_mapper
()
.
location_map
.
find_one
({
'_id.org'
:
org
,
'_id.course'
:
course
})
'_id'
:
{
'org'
:
org
,
'course'
:
course
}
})
self
.
assertIsNotNone
(
entry
,
"Didn't find entry"
)
self
.
assertIsNotNone
(
entry
,
"Didn't find entry"
)
self
.
assertEqual
(
entry
[
'course_id'
],
'foo_org.geek_dept.quux_course.baz_run'
)
self
.
assertEqual
(
entry
[
'course_id'
],
'foo_org.geek_dept.quux_course.baz_run'
)
self
.
assertEqual
(
entry
[
'draft_branch'
],
'wip'
)
self
.
assertEqual
(
entry
[
'draft_branch'
],
'wip'
)
...
...
mongo_indexes.md
0 → 100644
View file @
3bd76f98
These are the indexes each mongo db should have in order to perform well.
Each section states the collection name and then the indexes. To create an index,
you'll typically either use the mongohq type web interface or a standard terminal console.
If a terminal, this assumes you've logged in and gotten to the mongo prompt
```
mongo mydatabasename
```
If using the terminal, to add an index to a collection, you'll need to prefix
```ensureIndex```
with
```
db.collection_name
```
as in
```db.location_map.ensureIndex({'course_id': 1}{background: true})```
location_map:
=============
```
ensureIndex({'_id.org': 1, '_id.course': 1})
ensureIndex({'course_id': 1})
```
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