[JAVA-548] BasicDBObject does not allow to create negated regular expression Created: 02/Apr/12  Updated: 13/Mar/14  Resolved: 13/Mar/14

Status: Closed
Project: Java Driver
Component/s: API
Affects Version/s: 2.7.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Oliver Gierke Assignee: Unassigned
Resolution: Done Votes: 1
Labels: query, regex
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

To create a negating regular expression predicate I essentially need to create the following JSON query:

{ $not : /myregex/ }

Unfortunately this is not possible with BasicDBObject as its toString() method (which essentially calls JSON.serialize(...)) wraps the value into quotation marks in any case which results in the following output:

{ "$not" : "/myregex/" }

This is rejected by the driver with the following message:

error: { "$err" : "invalid use of $not", "code" : 13041 }

The crucial part is the value being wrapped into quotation marks. So I think the driver should not escape the value for a $not key if it is a String as it usually only works with another operator wrapped into yet another DBObject. Would be also cool if a new BasicDbObject("$not", Pattern.compile("myRegex")) would create the correct representation as well. Currently this creates:

{ $not : { $regex : "myRegex", $options : ""}}

which is rejected by the driver as well.



 Comments   
Comment by Jeffrey Yemin [ 13/Mar/14 ]

Hi Oliver,

I'm closing this as Works as Designed. I'm aware that you don't like the design...

In 3.0, we will most likely have a JSONWriter class that is capable of producing shell-compatible output.

Comment by Oliver Gierke [ 04/Apr/12 ]

Well, I just think that it's highly problematic that the BasicDBObject has a toString() representation that not only is not what get's send to the server but even might produce output that cannot be executed on the Mongo shell. Here is just another example of where this led the user into debugging hell as he also assumed the BasicDBObject representation was what gets sent to the server.

So currently …

DBObject query = new BasicDBObject("$not", Pattern.compile("myPattern"));
System.out.println(query.toString());

… produces …

{ $not : { $regex : "myRegex", $options : "" }}

… which gets rejected by the server, although executing the query instance works, as does …

{ $not : /myRegex/ }

So what I am arguing is that BasicDBObject.toString() should produce a representation which can actually be copied to the shell and executed and not create the impression that it was set up incorrectly where it actually wasn't.

Comment by Jeffrey Yemin [ 02/Apr/12 ]

Not sure what else we can do here, Oliver, as there is no native representation for regular expression in JSON. We have a similar problem for other types, like Binary, ObjectId, Date, Timestamp, etc. See http://www.mongodb.org/display/DOCS/Mongo+Extended+JSON.

Comment by Oliver Gierke [ 02/Apr/12 ]

Thanks for the reply, Scott. It seems I've been struck by the impression the toString() representation of a BasicDbObject would actually represent what would be serialized to the server on execution but apparently the BasicBSONEncoder treats the values slightly differently (and in fact correct).

So is it possible to get the toString() representation of BasicDbObject a bit more closer to what BasicBSONEncoder actually writes? Otherwise it's hard to debug what's going wrong if something goes wrong. Feel free to change the ticket title to what this actually boils down to.

Comment by Scott Hernandez (Inactive) [ 02/Apr/12 ]

Why are you converting to strings or from them? That is not a valid option in this, or many, cases.

Generated at Thu Feb 08 08:52:32 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.