Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-13779

Allow $not to be applied to $regex (currently only /regex/ syntax is allowed)

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Major - P3
    • Resolution: Done
    • 2.4.10, 2.6.0
    • 4.0.7, 4.1.8
    • Querying
    • None
    • Fully Compatible
    • v4.0
    • Query 2019-02-11

    Description

      Executing the following queries I was expecting the same result but apparently they are dealt differently:

      2 scenarios

      • matching

        nair(mongod-2.7.0-pre-) test> db.system.namespaces.find({ name:/\$/} )
        {
          "name": "test.data.$_id_"
        }
        {
          "name": "test.difference.$_id_"
        }
        {
          "name": "test.posts.$_id_"
        }
        {
          "name": "test.kunal.$_id_"
        }
        {
          "name": "test.maha_example.$_id_"
        }

        has the same result has using $regex operator

        nair(mongod-2.7.0-pre-) test> db.system.namespaces.find({ name:{ $regex: "\\$"}} )
        {
          "name": "test.data.$_id_"
        }
        {
          "name": "test.difference.$_id_"
        }
        {
          "name": "test.posts.$_id_"
        }
        {
          "name": "test.kunal.$_id_"
        }
        {
          "name": "test.maha_example.$_id_"
        }

      • not matching query

        nair(mongod-2.7.0-pre-) test> db.system.namespaces.find({ name: {$not: /\$/}} )
        {
          "name": "test.system.indexes"
        }
        {
          "name": "test.data"
        }
        {
          "name": "test.difference"
        }
        {
          "name": "test.posts"
        }
        {
          "name": "test.kunal"
        }
        {
          "name": "test.maha_example"
        }
        {
          "name": "test.system.profile",
          "options": {
            "capped": true,
            "size": 1048576
          }
        }

        But using $regex operator fails

        nair(mongod-2.7.0-pre-) test> db.system.namespaces.find({ name: {$not:  { $regex: "\\$"}}} )
        error: {
          "$err": "Can't canonicalize query: BadValue $not cannot have a regex",
          "code": 17287
        }

      Is this the expected behaviour ? and if so why ?

      Looking deeper in the code I can also see the following comment:
      mongo/db/matcher/expression_parser_tree.cpp:103

      ...
               // TODO: this seems arbitrary?
               // tested in jstests/not2.js
               for ( unsigned i = 0; i < theAnd->numChildren(); i++ )
                   if ( theAnd->getChild(i)->matchType() == MatchExpression::REGEX )
                       return StatusWithMatchExpression( ErrorCodes::BadValue, "$not cannot have a regex" );
      ...

      and looking int the jstests it makes even less sense:

      jstests/core/not2.js

        49 check( {i:{$not:/a/}}, "b" );
        50 check( {i:{$not:/(a|b)/}}, "", 0 );
        51 check( {i:{$not:/a/,$regex:"a"}}, "", 0 );
        52 check( {i:{$not:/aa/}}, "a", 2 );
        53 fail( {i:{$not:{$regex:"a"}}} );
        54 fail( {i:{$not:{$options:"a"}}} );

      Attachments

        Issue Links

          Activity

            People

              james.wahlin@mongodb.com James Wahlin
              norberto.leite Norberto Fernando Rocha Leite (Inactive)
              Votes:
              8 Vote for this issue
              Watchers:
              45 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: