davidlatwe / montydb

Monty, Mongo tinified. MongoDB implemented in Python !

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support regexes with `$not`

dgutson opened this issue · comments

Seems that this is not implemented:

{"$not": {"$regex": "(?i)Hello World"}}

output:

{"time":"2023-07-19T20:12:37Z","message":"  File \"/usr/local/lib/python3.10/site-packages/montydb/engine/queries.py\", line 381, in _parse_not"}
{"time":"2023-07-19T20:12:37Z","message":"    raise OperationFailure(\"$not cannot have a regex\")"}
{"time":"2023-07-19T20:12:37Z","message":"montydb.errors.OperationFailure: $not cannot have a regex"}
{"time":"2023-07-19T20:12:37Z","message":"ERROR:root:$not cannot have a regex"}

@davidlatwe I was about to work to fix this issue and I noticed that when given a regex instance the parser uses it, for example:

 { "field": {"$not": bson.Regex("(?i)Hello World") } }

Works as intended because of this:

def _parse_not(self, sub_spec):
. Internally that's being handled as a "$regex" node, so I don't understand why the "$regex" node is disallowed when used in the subdocument.

As a side note, in MongoDB the following is valid: { "field": { "$not": { "$regex": "(?i)Hello World" } }}

Hey @arieltorti and @dgutson

The reason it's being blocked might be because the MongoDB version at the time I was implementing didn't allow it.

Which MongoDB version are you using?

You may have a look at the bottom of montydb/configure.py, there's some function patching for adjusting the behavior of montydb to match against a specific mongodb version.

I was tended to make sure montydb behaves exactly the same as the targeted mongodb version to avoid any unexpected result when the production code switching back to a real mongodb. Hope that make sense. 😄

Tried on MongoDB 4.2 and 4.4. I just validated Mongo 3.6 and it fails as you mentioned:

Error: error: {
	"ok" : 0,
	"errmsg" : "$not cannot have a regex",
	"code" : 2,
	"codeName" : "BadValue"
}

Is there a way to configure montydb in a Mongo 4 compatible way to emulate this behavior?

Yes, you need to call set_storage before getting a client, take in-memory storage as example:

from montydb import MontyClient, set_storage


set_storage(
    repository=":memory:",
    storage="memory",
    mongo_version="4.0",  # available version: "3.6", "4.0", "4.2", "4.4"
)

client = MontyClient(":memory:")
...

@davidlatwe meaning: a fix has to be done in order to restore the behavior for mongodb 4.x?

Yeah, and I think I can take a deeper look at this weekend.

I'll take the query from the first comment as test case, do add more failed cases if you could.

Pull requests are welcomed too, do let me know if you guys have any issue on fixing/improving montydb.

🍻

@davidlatwe let me know if you're happy with that fix or we need to change it

The fix has been merged and released in 2.5.1, closing this now.