Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

I run the following queries on a collection that have a lot of entries that contain [ and ].

 db.test.find({word:/[\[]/});           // could not be run in console
 db.test.find({word:/\[/ });            // could not be run in console
 db.test.find({word:/\]/});             //returns result
 db.test.find({word:/[\]]/});           //returns result
 db.test.find({word:{$regex:"\["}});    //no result
 db.test.find({word:{$regex:"\[[]"}});  //returns result

Why using \[ is such strange? Is it a bug?

I am using mongodb 2.2.0, perhaps

share|improve this question
    
What are you actually trying to search for? Explain in plain English –  Phil Nov 6 '12 at 21:02
    
@Phil I am search for entries that contains opening square bracket –  PHPst Nov 7 '12 at 3:06
add comment

1 Answer 1

There are multiple issues here:

  • First, your console queries work fine in MongoDB v2.0.2 but don't work in MongoDB v2.2.1. This is probably a regression bug, but the JavaScript parser may have intentionally been changed between versions. The ... after entering a command means the console is waiting for a multi-line command to be completed; I'm not sure why in this specific situation.
  • Also, the backslash character \ in the $regex string must itself be escaped. (The JavaScript parser consumes the escape first, before the regex engine gets to see it.)
> db.test.find({word:{$regex:"\["}});    // no result
> db.test.find({word:{$regex:"\\["}});   // returns result when escaped properly
{ "_id" : 0, "word" : "[" }
{ "_id" : 1, "word" : "[]" }

MongoDB 2.0.2 console output:

> db.test.drop(); version()
version: 2.0.2
>
> db.test.insert({_id: 0, word: '['});
> db.test.insert({_id: 1, word: '[]'});
> db.test.insert({_id: 2, word: ']'});
> db.test.insert({_id: 9, word: 'no brackets'});
>
> db.test.find({word:/[\[]/});           // could not be run in console
{ "_id" : 0, "word" : "[" }
{ "_id" : 1, "word" : "[]" }
> db.test.find({word:/\[/ });            // could not be run in console
{ "_id" : 0, "word" : "[" }
{ "_id" : 1, "word" : "[]" }
> db.test.find({word:/\]/});             //returns result
{ "_id" : 1, "word" : "[]" }
{ "_id" : 2, "word" : "]" }
> db.test.find({word:/[\]]/});           //returns result
{ "_id" : 1, "word" : "[]" }
{ "_id" : 2, "word" : "]" }
> db.test.find({word:{$regex:"\["}});    //no result
> db.test.find({word:{$regex:"\\["}});   //returns result when escaped properly
{ "_id" : 0, "word" : "[" }
{ "_id" : 1, "word" : "[]" }
> db.test.find({word:{$regex:"\[[]"}});  //returns result
{ "_id" : 0, "word" : "[" }
{ "_id" : 1, "word" : "[]" }

MongoDB 2.2.1 console output:

> db.test.drop(); version()
version: 2.2.1
>
> db.test.insert({_id: 0, word: '['});
> db.test.insert({_id: 1, word: '[]'});
> db.test.insert({_id: 2, word: ']'});
> db.test.insert({_id: 9, word: 'no brackets'});
>
> db.test.find({word:/[\[]/});           // could not be run in console
... db.test.find({word:/\[/ });            // could not be run in console
... db.test.find({word:/\]/});             // returns result
... db.test.find({word:/[\]]/});           // returns result
{ "_id" : 1, "word" : "[]" }
{ "_id" : 2, "word" : "]" }
> db.test.find({word:{$regex:"\["}});    // no result
> db.test.find({word:{$regex:"\\["}});   // returns result when escaped properly
{ "_id" : 0, "word" : "[" }
{ "_id" : 1, "word" : "[]" }
> db.test.find({word:{$regex:"\[[]"}});  // returns result

MongoDB 2.2.1 console output (commented out lines that don't parse as expected):

> db.test.drop(); version()
version: 2.2.1
>
> db.test.insert({_id: 0, word: '['});
> db.test.insert({_id: 1, word: '[]'});
> db.test.insert({_id: 2, word: ']'});
> db.test.insert({_id: 9, word: 'no brackets'});
>
> // db.test.find({word:/[\[]/});        // could not be run in console
> // db.test.find({word:/\[/ });         // could not be run in console
> db.test.find({word:/\]/});             // returns result
{ "_id" : 1, "word" : "[]" }
{ "_id" : 2, "word" : "]" }
> db.test.find({word:/[\]]/});           // returns result
{ "_id" : 1, "word" : "[]" }
{ "_id" : 2, "word" : "]" }
> db.test.find({word:{$regex:"\["}});    // no result
> db.test.find({word:{$regex:"\\["}});   // returns result when escaped properly
{ "_id" : 0, "word" : "[" }
{ "_id" : 1, "word" : "[]" }
> db.test.find({word:{$regex:"\[[]"}});  // returns result
{ "_id" : 0, "word" : "[" }
{ "_id" : 1, "word" : "[]" }
>
share|improve this answer
    
db.test.find({word:{$regex:"\]"}}); // returns result even when not escaped –  PHPst Nov 8 '12 at 4:17
1  
@Reza: that is because ] is not always a special RegEx character. Where there is no matching opening [ character RegEx treats it like a literal ] character. JavaScript is still escaping the string first, so RegEx actually only sees "]" –  Leftium Nov 8 '12 at 6:05
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.