Mongoengine - request how to filter by size of ListField

I have the following model:

class Like(EmbeddedDocument): user = ReferenceField(User,dbref=False) date = DateTimeField(default=datetime.utcnow,required=True) meta = {'allow_inheritance': False} class Post(Document): name = StringField(max_length=120, required=True) likes = ListField(EmbeddedDocumentField(Like)) 

I would like to filter only messages with more than 20 likes (ListField larger than 20). I tried to execute the request:

 posts = Post.objects.filter(likes__size_gte=20) posts = Post.objects.filter(likes_gte=20) posts = Post.objects.filter(likes__gte=20) posts = Post.objects.filter(likes__size_gte=20) 

None of them work.

But if I use exact matching (the ListField is exactly 20 in size), it works:

 posts = Post.objects.filter(likes__size=20) 

Comments?

+7
source share
2 answers

Far from an ideal solution, but you can make with an unprocessed request mango and $ where is the operator, for example:

 posts = Post.objects.filter(__raw__={'$where': 'this.likes.length > 20'}) 

Another option, which should work faster, but, in my opinion, is less clear, is to check if the 21st element exists:

 posts = Post.objects.filter(likes__21__exists=True) 

The second option only works if you are using MongoDB 2.2 +

Source: taken from these answers and applied to MongoEngine.

+8
source

You cannot use $ size for a range of values.

From mongo website:

$ size does not accept ranges of values. To select documents based on fields with different number of elements, create a counter field that you increase when adding elements to the field.

This is a link to the corresponding question that led to the answer: delete documents with an array field size of less than 3 in mongoDB

This is the mongo page linked to the previous link that provided the documentation in the block above: http://docs.mongodb.org/manual/reference/operator/size/#_S_size

Try adding a counter field as suggested in the text block.

+4
source

All Articles