1

Trying to build a mongoose query with regex but for some reason it always returns zero results.

I have a model called Place with value wind_direction. wind_direction is a string and looks something like this:

place.wind_direction = "SW, WSW, W, WNW, NW, NE, ENE, E";

I get values through a form, in this case "W, WNW, NW" and try to build a regex like this:

var string = JSON.stringify(req.body.wind_direction)
string = string.replace(/[\[\]"]+/g,'').split(",")
var reg = ""
for(var i = 0; i < string.length; i++){
   reg += "\b" + string[i] + "\b|";
}
reg = "/" + reg.substring(0, reg.length - 1) + "/";
query.wind_direction = { "$regex": reg, "$options": "i" }

When i console.log my query it looks like this:

{ wind_direction: { '$regex': '/\bW\b|\bWNW\b|\bNW\b/', '$options': 'i' } }

Then when I run a simple query with Place.find(query, function(req,res... it returns no results. But when I test my regex in an online regex tester it works.

Plaksel
  • 160
  • 3
  • 13
  • 1
    Try just `query.wind_direction = { "$regex": new RegExp("\\b(?:" + req.body.wind_direction.join("|") + ")\\b"), "$options": "i" }` or `query.wind_direction = { "$regex": "\\b(?:" + req.body.wind_direction.join("|") + ")\\b", "$options": "i" }` – Wiktor Stribiżew Nov 06 '18 at 17:18
  • Thanks! First comment works for me. Didn't know about the existence of "?:" which makes life so much easier! – Plaksel Nov 06 '18 at 17:28
  • Just to make sure, `query.wind_direction = { "$regex": new RegExp("\\b(?:" + req.body.wind_direction.join("|") + ")\\b"), "$options": "i" }` works, right? Or the second one? – Wiktor Stribiżew Nov 06 '18 at 17:30
  • First one works for me – Plaksel Nov 06 '18 at 17:38

1 Answers1

2

It appears that your req.body.wind_direction is already an array that you may use to build the alternation pattern, there is no need to JSON.stringify this array. To build an alternation, you may use arr.join("|").

In order to avoid repeating \b, you may group all the alternatives, and a non-capturing group suits here best: \b(?:term1|term2|termN)\b.

You may use

query.wind_direction = { "$regex": new RegExp("\\b(?:" + req.body.wind_direction.join("|") + ")\\b"), "$options": "i" } 
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563