-->

Querying a list in mongoengine; contains vs in

2020-03-04 07:35发布

问题:

I have a ListField in a model with ids (ReferenceField), and I need to do a query if a certain id is in that list. AFAIK I have 2 options for this:

Model.objects.filter(refs__contains='59633cad9d4bc6543aab2f39')

or:

Model.objects.filter(refs__in=['59633cad9d4bc6543aab2f39'])

Which one is the most efficient for this use case?

The model looks like:

class Model(mongoengine.Document):
    refs = mongoengine.ListField(mongoengine.ReferenceField(SomeOtherModel))

From what I can read in the mongoengine documentation, http://docs.mongoengine.org/guide/querying.html#string-queries, contains is really a string query, but it works surprisingly here as well. But I'm guessing that __in is more efficient since it should be optimized for lists, or am I wrong?

回答1:

The string queries normally under the covers are all regex query so would be less efficient. However, the exception is when testing against reference fields! The following queries are:

Model.objects.filter(refs__contains="5305c92956c02c3f391fcaba")._query
{'refs': ObjectId('5305c92956c02c3f391fcaba')}

Which is a direct lookup.

Model.objects.filter(refs__in=["5305c92956c02c3f391fcaba"])._query
{'refs': {'$in': [ObjectId('5305c92956c02c3f391fcaba')]}}

This probably is less efficient, but would probably be extremely marginal. The biggest impact would be the number of docs and whether or not the refs field has an index.