How to query Mongo for information about a course or a course's content.

Settings scoped fields are stored in the db.modulestore.structures collection in Mongo.

Content scoped fields are stored in the db.modulestore.definitions collection in Mongo.


In order to query for a course in the structures collection, you need the ObjectId associated with the latest version of the structure you are interested in. This ObjectId is stored in the db.modulestore.active_versions collection. The reason this is important is that we store historical course structures, so querying either of the above collections directly first may get you an older version of the structure. There is a workaround described at the end of this document.


In order to get the ObjectId associated with a particular structure in a course, you can run the following query.

db.modulestore.active_versions.find({"course": "<COURSE>", "org": "<ORG>", "run": "<RUN>"}).pretty()


For example,

Query:

db.modulestore.active_versions.find({"course": "StudioX", "org": "edX", "run": "3T2018"}).pretty()


Output:

{
	"_id" : ObjectId("5b6da34d34bc120b28d81a9d"),
	"run" : "3T2018",
	"search_targets" : {
		"wiki_slug" : "edX.StudioX.3T2017"
	},
	"versions" : {
		"draft-branch" : ObjectId("5d7b97911d27c83a078ff767"),
		"published-branch" : ObjectId("5d7b97871d27c83814bd13fd")
	},
	"schema_version" : 1,
	"last_update" : ISODate("2019-09-13T13:20:17.536Z"),
	"course" : "StudioX",
	"edited_on" : ISODate("2018-08-10T14:38:05.816Z"),
	"org" : "edX",
	"edited_by" : NumberLong(10442141)
}


The ObjectIds that we are interested in are the ones in the document with the key versions. The ObjectId associated with the key draft-branch is for the draft version of the course structure. The ObjectId associated with the key published-branch is for the public version of the course structure. You can roughly think about these as what you see in Studio and what you see on the LMS, respectively. Most of the time, you're likely to be interested in the `published-branch` ObjectId.


Next, you use this ObjectId to query either of the aforementioned collections.


Let's say we're looking for a Settings scoped field, so we're looking in the db.modulestore.structures collection. You can run the following query.

db.modulestore.structures.find({"_id": ObjectId("<ObjectId>")}).pretty()

For example,

Query:

db.modulestore.structures.find({"_id": ObjectId("5d7b97871d27c83814bd13fd")}).pretty()

I am not posting the output, because it is very large. You can look through the JSON to find the field you are looking for.


Note that we likely do not store defaults in these collections (not entirely sure). That is, if a field has not been set explicitly, it will not be in the collection. If you do not see the field you are looking for in the collection, you can assume that the default is being used.


An alternative to looking for the structure's ObjectId is to query either the structures or definitions collection directly and order descending by the ObjectId in the _id field. This is because "ObjectIDs are made with a timestamp element implicit in them, so getting the highest one that matches your query will likely do the trick" (Dave Ormsbee). However, this may give you a draft structure.