Question

I have this 2 commands in mongodb:

1.- db.tag.find({$where:"'star wars episode VII'.search(this.name) >= 0"})
2.- db.tag.find({$where: "/this.name/.test('star wars episode VII')"})

and the collection below:

db.tag.find()
{ "_id" : ObjectId("536f7107c55b2acc61000bc8"), "name" : "star" }
{ "_id" : ObjectId("536f710fc55b2acc61000bc9"), "name" : "star wars" }
{ "_id" : ObjectId("536f7117c55b2acc61000bca"), "name" : "spider" }
{ "_id" : ObjectId("537087d16ac5b5f6f58f0b1b"), "name" : "starting" }

Question:

Why option 1 is returning the data I need but option 2 is not giving any output? what is the problem with option 2?

e.g.

db.tag.find({$where:"'star wars episode VII'.search(this.name) >= 0"})
{ "_id" : ObjectId("536f7107c55b2acc61000bc8"), "name" : "star" }
{ "_id" : ObjectId("536f710fc55b2acc61000bc9"), "name" : "star wars" }

thank you very much

SOLUTION: by Neil Lunn

2.- db.tag.find(function(){ var patt = new RegExp(this.name); return patt.test("star wars episode VII"); })
Was it helpful?

Solution

Probably your best litmus test for this is using a JavaScript REPL, much like the mongo shell with your basic principle which is:

var string = "star wars episode VII";
/string/.test("star wars episode VII - a new disney");

Which of course is just going to return false.

The general problem here is that you cannot use a variable within the /../ syntax of a regular expression and to do so you would actually need to define this as a RegExp object like so:

var patt = new RegExp("star wars episode VII");
patt.test("star wars episode VII - a new disney");

So the two statements are not actually equal, and therefore one returns true while the other form returns false.

It is kind of true ( though equally horrible to the JavaScript execution ) that you do not need this at all, and could simply do a Regex search:

db.tag.find({ "name": /star wars episode VII/ })

MongoDB supports that, but it really isn't advised, but either is usage of the $where operator. See $regex for more information.

OTHER TIPS

In your second query, should you not go the other way round ?

db.tag.find({$where: "/star wars episode VII/.test(this.name)"})

On the other hand, I would suggest these expressions, which will do exactly the same without a $where clause:

db.tag.find({ name: /star wars episode VII/ });

or

db.tag.find({ name: { $regex: {"star wars episode VII"} } );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top