How to do negative regex query using Java driver

991 views
Skip to first unread message

Temujin_12

unread,
Nov 3, 2011, 5:59:48 PM11/3/11
to mongodb-user
This is has sort-of been asked in different ways but I don't see any
satisfactory answer.

Let me see if I can explain it (using MongoDB 2.0.1 and java driver
2.6.5):

From console:
(yes, i know I don't have use extended $and syntax here, but bear with
me)
=========================================================
> db.test.find()
{ "_id" : ObjectId("4eb1863ada7081653c47bf38"), "id" : 1, "data" :
"foo" }
{ "_id" : ObjectId("4eb18642da7081653c47bf39"), "id" : 1, "data" :
"fooDup" }
> db.test.find({"$and": [{"data" : { $not : {$regex : '^foo$', $options : 'i'}}}, {"id" : 1}]})
error: {
"$err" : "can't use $not with $regex, use BSON regex type instead",
"code" : 13032
}
> db.test.find({"$and": [{"data" : { $not : !/^foo$/i}}, {"id" : 1}]})
error: { "$err" : "invalid use of $not", "code" : 13041 }
> db.test.find({"$and": [{"data" : /^foo$/i }, {"id" : 1}]})
{ "_id" : ObjectId("4eb1863ada7081653c47bf38"), "id" : 1, "data" :
"foo" }
> db.test.find({"$and": [{"data" : !/^foo$/i }, {"id" : 1}]})
=========================================================

Okay, I see that $not and regexes don't play well together.

However, in the Java driver, it appears that Pattern objects are
always sent using the extended $regex syntax (correct me if I'm
wrong).

Does this mean that there is no way to do *negative* regex queries
using the Java driver? Is there a bug or feature gap in the Java
driver.

And for the record, Java regex makes me frustrated. Why did they have
to go off and do their own thing?

Scott Hernandez

unread,
Nov 4, 2011, 5:25:21 AM11/4/11
to mongod...@googlegroups.com
Do you have a working example from the javascript shell?

> --
> You received this message because you are subscribed to the Google Groups "mongodb-user" group.
> To post to this group, send email to mongod...@googlegroups.com.
> To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.
>
>

Temujin_12

unread,
Nov 4, 2011, 10:33:00 AM11/4/11
to mongodb-user
The example I posted above was from the javascript shell (I called it
"console").

What I'm having trouble doing is getting the Java driver to do a
negative regex query (does *NOT* match the regex ....).

Temujin_12

unread,
Nov 4, 2011, 12:10:51 PM11/4/11
to mongodb-user
Put another way:

The Java API uses the Pattern java type. However, there is no way to
express a negative regex using the Pattern API (ie: !/^foo/i).

You can express the expanded $regex mongo condition by building it
yourself using a BasicDBObject, however there appears to be no way to
express a negative regex using the $regex mongo condition syntax.
Attempting to use the $not modifier causes the error shown above.

Since the Java driver seems to always use the expanded $regex syntax,
I don't see a way (using the Java driver) to do negative regex
queries.

Now that I read through the regex documentation more closely, I see
that there isn't an example using a negative regex.

Perhaps I should ask if Mongo's regular expressions support negative
expressions like:
* !/^abc/ - any string that does *NOT* begin with 'abc'
* !/.*abc$/ - any string that does *NOT* end with 'abc'

And if it does not, is there a way to express this otherwise?

mdahlman

unread,
Nov 4, 2011, 12:34:20 PM11/4/11
to mongodb-user
Sure, you can do a negative regex. For example, this gets fields that
do not start with "a":

/^[^a]/

It works for me with the Java driver against a trivial data set.

-Matt

Scott Hernandez

unread,
Nov 4, 2011, 12:44:09 PM11/4/11
to mongod...@googlegroups.com
On Fri, Nov 4, 2011 at 12:10 PM, Temujin_12 <caleb...@gmail.com> wrote:
> Put another way:
>
> The Java API uses the Pattern java type. However, there is no way to
> express a negative regex using the Pattern API (ie: !/^foo/i).
>
> You can express the expanded $regex mongo condition by building it
> yourself using a BasicDBObject, however there appears to be no way to
> express a negative regex using the $regex mongo condition syntax.
> Attempting to use the $not modifier causes the error shown above.
>
> Since the Java driver seems to always use the expanded $regex syntax,
> I don't see a way (using the Java driver) to do negative regex
> queries.

This is incorrect, it does not use that form. It just prints that so
it is more readable from toString.

Temujin_12

unread,
Nov 4, 2011, 12:56:12 PM11/4/11
to mongodb-user
Ok, that makes sense.

I think that I am also mistaken about the leading '!' (eg: !/^abc/). I
believe that is not PCRE compliant and that one cannot use the same
regex and apply a meta-level negative flag or modifier.

As you pointed out, it looks like one must use negative look behinds
or look aheads to express this kind of negative.

I believe that I got my misinformation from PCRE tables used in
postfix (which allow that !/^abc/ syntax). See http://www.postfix.org/pcre_table.5.html.

Thanks for setting me straight.

:-)

On Nov 4, 9:44 am, Scott Hernandez <scotthernan...@gmail.com> wrote:

Temujin_12

unread,
Nov 4, 2011, 12:59:06 PM11/4/11
to mongodb-user
BTW, is there any reason why not to allow $not with regular
expressions?

On Nov 4, 9:56 am, Temujin_12 <calebjo...@gmail.com> wrote:
> Ok, that makes sense.
>
> I think that I am also mistaken about the leading '!' (eg: !/^abc/). I
> believe that is not PCRE compliant and that one cannot use the same
> regex and apply a meta-level negative flag or modifier.
>
> As you pointed out, it looks like one must use negative look behinds
> or look aheads to express this kind of negative.
>
> I believe that I got my misinformation from PCRE tables used in
> postfix (which allow that !/^abc/ syntax). Seehttp://www.postfix.org/pcre_table.5.html.
Reply all
Reply to author
Forward
0 new messages