Dynamic collection.find $or condition in NodeJS

1.2k views Asked by At

I need to generate an $or filter from passed strings in an array to select documents from a 20K documents' collection.

So I wrote the following function which generates the $or condition:

function orConditionCreator(attName, tagsArray)
{
    var myarray = [];
    var myJSON = "";
    for (var i = 0; i < tagsArray.length; i++) {
        var key = attName;
        var json = { };
        // forming regex with case insensitivity
        json[key] = "/" + tagsArray[i] + "/i";      
        myarray.push(json);
    }

    myJSON = JSON.stringify({ $or: myarray });
    // myJSON contains quotes like in { "name" : "/HarryPotter/i" } 
    // this is not desirable for regex. So we strip the quotes
    myJSON = myJSON.replace(/\"/g, "");
    return myJSON;
 }

Then I call it like :

//tags[0] = "harry" , tags[1] = "potter"
var orCondition = orConditionCreator("name", tags);
mongo.peopleColl.find( orCondition ).toArray( function( err, documents) {
    if(err) {  /* handle */    }
    // do stuff with documents
});

Here, find(orCondition) is not working as expected. Now, if I manually pass the string returned by orConditionCreator to collection.find() as

 mongo.peopleColl.find( {$or:[{name:/harry/i},{name:/potter/i}]} ).toArrarray(...

it works fine, but fails in first case with use of orCondition variable.

Any help regarding the dynamic creation of this $or condition would be great. Thanks!

1

There are 1 answers

2
JohnnyHK On BEST ANSWER

This reason this isn't returning any docs, is that orConditionCreator is returning a JSON string, not an object.

But like I mentioned in the comments, you should be using $in for this instead:

//tags[0] = "harry" , tags[1] = "potter"
var regexps = tags.map(function(tag) {
    // When building regular expressions from strings, use the constructor.
    return new RegExp(tag, "i");
});
mongo.peopleColl.find({name: {$in: regexps}}).toArray(function(err, documents) {
    if(err) {  /* handle */    }
    // do stuff with documents
});