Mongoengine: `pull` not working for EmbeddedDocumentListField, only working for ListFields

Created on 22 Apr 2017  路  5Comments  路  Source: MongoEngine/mongoengine

Hi,
I am using mongoengine. I have came across a weird issue when I was trying to use pull and push for ListFields and EmbeddedDocumentListFields. I realised it is a issue in mongoengine (according to me). The issue is one cannot do a pull query from a EmbeddedDocumentListField but can do the same in ListField.

I traced down this issue and found in mongoengine.queryset.transform.update() has a different logic to handle pull among UPDATE_OPERATORS in case key has . , Under this condition only ListField are allowed to reform key with . operator due to which a query like - embfield__emb_list_field will result in {'emb_field': {'emb_list_field': whereas it should be {'emb_field.emb_list_field':.

Let me know if this is a bug or I am making some mistake and if its a bug can i submit a patch to fix this

Most helpful comment

All 5 comments

Can you provide sample of your code in order to get error and understand your problem fully. If you show the code sample, someone would be able to help.

Hi, I am glad that you replied. Below is the code snippet which I was using and found this issue.

class Identity(document.EmbeddedDocument):
    class Address(document.EmbeddedDocument):
          pincode = fields.StringField()
          city = fields.StringField()

    registeration_number = fields.StringField()
    address = fields.EmbeddedDocumentListField(fields.EmbeddedDocumentField())
class Company(documents.Document):
    company_ids = fields.EmbeddedDocumentField(Identity)

Now I an performing certain operations where I came across this issue -
comp = Company.objects.first()
add_1 = Identity.Address()
comp.update(push__company_ids__address=add_1) <-- Runs fine
comp.update(pull__company_ids__address=add_1) <-- throws Operation Error

This is the Exact Error which I get -
OperationError: Update failed (Cannot apply $pull to a non-array value)

After running debugger I found that in mongoengine/queryset/base in update funtion. the update dict that gets created is -
{'$pull': {'company_ids': {'address': SON(Address Object)}}

Also for list field of such cases it creates -
{$pull: {'company_ids.address': SON(Address Object)}

In case the address field in Identity class is ListField both Push and Pull runs fine.

mongo_update value for push operation
{'company_ids.address': SON([('pincode', u'1234'), ('city', u'UB')])}}
mongo_update value for pull operation
{'$pull': {'company_ids': {'address': SON([('pincode', u'1234'), ('city', u'UB')])}}}

In my opinion, these values are supposed to be same, then it is considered as a bug.
You should send PR, let the contributors decide if it's merge or drop. Otherwise, you will be fine in case that of using ListField :)

Looks like PR got merged, can we close this?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mlorant picture mlorant  路  5Comments

MateuszBelczowski picture MateuszBelczowski  路  4Comments

nilay-gpt picture nilay-gpt  路  4Comments

ZEROF picture ZEROF  路  4Comments

MaXXXXfeng picture MaXXXXfeng  路  3Comments