user3128461
user3128461

Reputation: 99

Node JS Mongo Find($where) Returning All Records

I have a database connection and request setup. The "myregex" is assigned as a BSONRegExp field type and has regex stored inside. I have tested the query

db.secondaryregextest.find(function() { return this.myregex.test('a'); } )

Inside the Mongodb shell and it returns the proper records. However, when attempting to migrate the query into node JS I receive all records in the collection, not just those that match the stored regex values.

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";

MongoClient.connect(url, function(err, db) {
  if (err) throw err;
    var dbo = db.db("Testing");
    
    dbo.collection("secondaryregextest").find( { $where: function() { return this.myregex.test('a') } } ).toArray(function (err,result) {
        if (err) {

            console.log(err);

        } else {
        
            console.log(result);
        }
    });
    
 
});

To reiterate, that search function works in the mongoDB shell but I believe I am perhaps incorrectly formatting the query in Node JS but am unable to locate an answer to my issue.

Update:

Based on @zx01 suggestion I reformed the query.

The following supports MongoDB's built-in JavaScript handling of queries.

dbo.collection("secondaryregextest").find( { $where: 'function() { return this.myregex.test("a") }' } ).toArray(function (err,result) {
    if (err) {
        console.log(err);
    } else {
        
        console.log(result);
    }
});

Upvotes: 0

Views: 263

Answers (1)

Jagadish Chauhan
Jagadish Chauhan

Reputation: 88

Reference of accepted answer from Mongodb $where query always true with nodejs

First off, keep in mind that the $where operator should almost never be used for the reasons explained here (credit goes to @WiredPrairie).

Back to your issue, the approach you'd like to take won't work even in the mongodb shell (which explicitly allows naked js functions with the $where operator). The javascript code provided to the $where operator is executed on the mongo server and won't have access to the enclosing environment (the "context bindings").

> db.test.insert({a: 42})
> db.test.find({a: 42})
{ "_id" : ObjectId("5150433c73f604984a7dff91"), "a" : 42 }
> db.test.find({$where: function() { return this.a == 42 }}) // works
{ "_id" : ObjectId("5150433c73f604984a7dff91"), "a" : 42 }
> var local_var = 42
> db.test.find({$where: function() { return this.a == local_var }})
error: {
    "$err" : "error on invocation of $where function:\nJS Error: ReferenceError: local_var is not defined nofile_b:1",
    "code" : 10071
}

Moreover it looks like that the node.js native mongo driver behaves differently from the shell in that it doesn't automatically serialize a js function you provide in the query object and instead it likely drops the clause altogether. This will leave you with the equivalent of timetables.find({}) which will return all the documents in the collection.

Upvotes: 1

Related Questions