How to include only selected embedded document in mongoengine?

1.3k views Asked by At

I'm fetching documents on the base of specific EmbeddedDocument, but I don't want to get all of the EmbeddedDocuments while retrieving, only the matched EmbeddedDocument with main Document.

Here's my code:

School Embedded Document

class School(EmbeddedDocument):
    name = StringField(max_length=120)

User Document

class User(Document):
    first_name = StringField(max_length=60, required=True)
    last_name = StringField(max_length=60)
    schools = EmbeddedDocumentListField(School)

Feeding documents:

user = User.objects.create(first_name="Rohit", last_name="Khatri")
user.schools = [
    School(name="Auden High School")),
    School(name="Baldwin Boys High School"),
    School(name="Baldwin Girls High School"),
    School(name="Aukamm Elementary School"),
    School(name="Mason-Rice Elementary")
]
user.save()

user = User.objects.create(first_name="ABC", last_name="DEF")
user.schools = [
    School(name="Little Harbor Elementary School")),
    School(name="Aukamm Elementary School"),
    School(name="Mason-Rice Elementary")
]
user.save()

I'm using this code the retrieve the users who have a particular school in their schools field:

users = User.objects(school__match={"name": "Aukamm Elementary School"})

I want to get only the selected school which is Aukamm Elementary School in the schools field.

Receiving

[
    {
        "first_name": "Rohit",
        "last_name": "Khatri",
        "schools": [
            {
                "name": "Auden High School"
            },
            {
                "name": "Baldwin Boys High School"
            },
            {
                "name": "Baldwin Girls High School"
            },
            {
                "name": "Aukamm Elementary School"
            },
            {
                "name": "Mason-Rice Elementary"
            }
        ]
    },
    {
        "first_name": "ABC",
        "last_name": "DEF",
        "schools": [
            {
                "name": "Little Harbor Elementary School"
            },
            {
                "name": "Aukamm Elementary School"
            },
            {
                "name": "Mason-Rice Elementary"
            }
        ]
    }
]

Required Output

[
    {
        "first_name": "Rohit",
        "last_name": "Khatri",
        "schools": [
            {
                "name": "Aukamm Elementary School"
            }
        ]
    },
    {
        "first_name": "ABC",
        "last_name": "DEF",
        "schools": [
            {
                "name": "Aukamm Elementary School"
            }
        ]
    }
]

Thanks

1

There are 1 answers

0
chridam On BEST ANSWER

You can use the $filter operator in the aggregate function as

users = User.objects(school__match={ "name": "Aukamm Elementary School" }).aggregate(
    { "$project": {
        "first_name": 1,
        "last_name": 1,
        "schools": {
             "$filter": {
                  "input": "$schools",
                  "as": "school",
                  "cond": { "$eq": [ "$$school.name", "Aukamm Elementary School" ] }
             }
        }
    } }
)