Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoengine list filtering

I have a list of required perms in some mongoengine's documents and I would like filtering on it.

Consider this Document:

class Entry(Document):
    required_perms = ListField(StringField())

e = Entry(required_perms=['create', 'update'])
e.save()

Here are some usecases:

all_perms = ['create', 'update', 'delete']

Entry.objects.filter(required_perms__in=all_perms)
[<Entry: Entry object>] # Returned because 'create' OR 'update' are in required_perms

Entry.objects.filter(required_perms__in=['create', 'delete'])
[<Entry: Entry object>] # Returned because 'create' is in required_perms

Entry.objects.filter(required_perms__all=all_perms)
[] # Not returned because 'delete' is not in required_perms

When querying with $in, I get the Entry, because at least one of the string is in the list. $all does not cover my needs because according to the doc it is the reverse of what I'm intending to do: "every item in list of values provided is in array" ; and I would like: "every item in array is in list of provided values".

So, I would like to request something like this:

Entry.objects.filter(everyoneof__required_perms__in=['create', 'delete'])

I tricked this to clearly explain it but this is ugly, not dynamic and should not be used:

Entry.objects(Q(required_perms__0__in=all_perms) & Q(required_perms__1__in=all_perms))
"""
Can be tested with: all_perms = ['create', 'delete'] -> No results
     and: all_perms = ['create', 'update', 'delete'] -> 1 result
"""

Is there a way to do something like that ? Maybe with a raw query ?

like image 321
Léo Avatar asked Jul 17 '26 17:07

Léo


1 Answers

If you know the order then you can do a direct check eg:

Entry.objects.filter(required_perms=['create', 'delete'])

If the order isn't fixed or known then you can use the $all operator:

Entry.objects.filter(required_perms__all=['create', 'delete'])

Update

If you have to ensure that all elements in a list match the given requirements AND that they may or may not be present - that is not supported. You'd have to do an __in= and then filter in your application.

I'm not sure of the approach. Why worry about user having extra permissions? Doesn't sound very flexible / future proof.

like image 81
Ross Avatar answered Jul 20 '26 07:07

Ross



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!