0

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!

Haywire
  • 858
  • 3
  • 14
  • 30
  • Can you edit your post to include the code for `orConditionCreator`? It's likely not returning what you think it is. Also, using `$in` instead of `$or` here would be much more efficient. – JohnnyHK Dec 11 '13 at 18:14
  • can you provide error message? You must have another bug, typo ...etc – damphat Dec 11 '13 at 18:16
  • @JohnnyHK: I have rolled back the original post to include `orConditionCreator`. Please check it. And as the name is a single string like `Harry Potter` so will $in still work? – Haywire Dec 11 '13 at 18:20
  • @damphat: There no error occurs. This query just quietly returns with no data at all. – Haywire Dec 11 '13 at 18:21

1 Answers1

1

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
});
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • Thanks @JohnnyHK! There's a typo in `RegExp` please fix it. It worked like a charm! I'll accept this as an answer. Still, I am curious to know if there is a way to make the string returned by `onConditionCreator` work (maybe converting it to some sort of string) ? – Haywire Dec 11 '13 at 19:12
  • @haywire Typo fixed--thanks for letting me know. You can convert a JSON string into an object via a call to `JSON.parse(str)`. – JohnnyHK Dec 11 '13 at 19:32