Pattern lookups casting their input $toString prevents indexes from being used

XMLWordPrintableJSON

    • Python Drivers
    • Needed
    • Hide

      Add to queries limitations:

      • Pattern matching lookups (:lookup:`iexact`, :lookup:`startswith`,
          :lookup:`istartswith`, :lookup:`endswith`, :lookup:`iendswith`,
          :lookup:`contains`, :lookup:`icontains`, :lookup:`regex`,
          and :lookup:`iregex`) don't support non-string fields.
      Show
      Add to queries limitations: Pattern matching lookups (:lookup:`iexact`, :lookup:`startswith`,   :lookup:`istartswith`, :lookup:`endswith`, :lookup:`iendswith`,   :lookup:`contains`, :lookup:`icontains`, :lookup:`regex`,   and :lookup:`iregex`) don't support non-string fields.
    • None
    • None
    • None
    • None
    • None
    • None

      In order to support pattern lookups (startswith, endswith, regex, etc.) on non-string fields, we cast the input using $toString. jib.adegunloye@mongodb.com reported that this causes poor performance on queries since the $toString prevents MongoDB from being able to uses indexes on the field. We'll remove this cast for now and try to add support for pattern lookups on non-string fields in the future (it's unclear how it could be done).

      class Author(models.Model):
          name = models.CharField(...)
      
      class Book(models.Model):
          author = models.ForeignKey(Author)
      
      >>> exp = json.loads(Book.objects.filter(author__name__icontains="0").explain())
      >>> pprint.pprint(exp['command']['pipeline'])
      [{'$lookup': {'as': 'polls_author',
                    'from': 'polls_author',
                    'let': {'parent__field__0': '$author_id'},
                    'pipeline': [{'$match': {'$expr': {'$and': [{'$eq': ['$$parent__field__0', '$_id']},
                                                                {'$regexMatch': {'input': {'$toString': '$name'},
                                                                                 'options': 'i',
                                                                                 'regex': '0'}}]}}}]}},
       {'$unwind': '$polls_author'},
       # Everything after the $unwind is redundant
       {'$match': {'$expr': {'$regexMatch': {'input': {'$toString': '$polls_author.name'},
                                             'options': 'i',
                                             'regex': '0'}}}}]

            Assignee:
            Tim Graham
            Reporter:
            Tim Graham
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: