slaayaah
slaayaah

Reputation: 101

How can you query embedded document that is null with mongoengine

I am new to mongoengine and querying. I got a document and an embedded document that looks like the following:

class Plan(EmbeddedDocument):
   name = StringField()
   size = FloatField()

class Test(Document):
   date = DateTimeField()
   plan = EmbeddedDocumentField(Plan)

How Can I get all Test-Documents that have no size set. That means that size=null/None? I tried it with __raw__ query, but this did not work for me..

Upvotes: 0

Views: 632

Answers (1)

bagerard
bagerard

Reputation: 6364

The way to query attribute of nested/embedded documents is done in the following manner (doc):

class LightSaber(EmbeddedDocument):
   color = StringField()
   length = FloatField()

class Jedi(Document):
    name = StringField()
    light_saber = EmbeddedDocumentField(LightSaber)


saber1 = LightSaber(color='red', length=32)
Jedi(name='Obiwan', light_saber=saber1).save()

saber2 = LightSaber(color='yellow', length=None)
Jedi(name='Yoda', light_saber=saber2).save()


Jedi(name='Rey', light_saber=None).save()

for jedi in Jedi.objects(light_saber__length=None):
    print(jedi.name)

# prints:
#     Yoda
#     Rey

That being said, by naming your attribute "size", you are hitting an edge case. In fact "size" is a mongoengine operator and so if you query Test.objects(plan__size=None), you'll get an error because MongoEngine believes that you want to make use of the size operator.

To do the same with __raw__, you need to use the following:

for jedi in Jedi.objects(__raw__={'light_saber.length': None}):
    print(jedi.name)

Using __raw__ works fine with "size" as well, in your example that would be: Test.objects(__raw__={'plan.size': None})

Upvotes: 1

Related Questions