Search code examples
pythonmongodbpymongo

Return only array field in MongoDB document


I have a MongoDB collection where each document has the following format:

    {
        "course_id": "course_id",
        "language": "language",
        "topics": [
            {
                "topic_id": "topic_id",
                "topic_title": "topic_title",
                "topic_description": "topic_description",
            },
        ],
    }

What I am trying to do is to retrieve, given a course_id and a language, an array (and only the array, not a document with the topics field) where each element has only the topic_id and topic_title fields, e.g.:

[
  {"topic_id": "id_1", "topic_title": "title1"},
  {"topic_id": "id_2", "topic_title": "title2"},
]

In order to retrieve only the array I used the .distinct() method as follows:

result = db.topics_collection.distinct("topics", {"course_id": course_id, "language": language})

Now I also need to filter out the topic_description field but the following query I tried did not work:

result = db.topics_collection.distinct("topics", {{"course_id": course_id, "language": language}, {"topic_description": 0}})

Is there another way (maybe also using a different method than .distinct()) to also filter out the topic_description field?


Solution

  • You can use the aggregate method for this kind of thing:

    result = db.topics_collection.aggregate([
      {
        $match: {
          course_id: course_id,
          language: language
        }
      },
      {
        $unwind: "$topics"
      },
      {
        $replaceRoot: {
          newRoot: "$topics"
        }
      },
      {
        $project: {
          topic_id: 1,
          topic_title: 1
        }
      }
    ])
    

    See HERE for a working example.

    Explanation:

    1. $match: your query condition.
    2. $unwind: the $topics array into separate documents.
    3. $replaceRoot: of the document with the $topics object from each of these new documents.
    4. $project: only the properties you want.