Long story short, I have in my MongoDB database a collection of posts and with node.js
, express
and mongoose
, I’m trying to find all the documents using the $where method.
So I try this and it works perfectly, all the results, if their name includes Jo
get returned.
app.get("/posts", (req, res) => {
const nameSearch = "Jo";
Post.find({
$where: function () {
return this.name.includes("Jo");
},
}).then((data) => res.send(data));
});
But if I do something like this, it throws me an error
app.get("/posts", (req, res) => {
const nameSearch = "Jo";
Post.find({
$where: function () {
return this.name.includes(nameSearch);
},
}).then((data) => res.send(data));
});
Also, if I do this, it says that $where
requires a string or a function.
function runThis(post) {
return post.name.includes("Jo");
}
app.get("/posts", (req, res) => {
Post.find({
$where: runThis(this),
}).then((data) => res.send(data));
});
Even weirder, I think, is that if I change the function inside the $where
to an arrow function
, no matter what I put in the function, it will return all the results
app.get("/posts", (req, res) => {
const nameSearch = "Jo";
Post.find({
$where: () => {
return this.name.includes("Jo");
},
}).then((data) => res.send(data));
});
2
Answers
Few things from the documentation
$where docs
About scope
You should avoid using
$where
About variables
I have no idea, but you can try using $let
Caveat: I don’t use Mongoose or MongoDb.
But the documentation says the function you pass for
$where
isn’t executed locally, it’s executed on the Mongoose server. So it doesn’t have access to the variable.But a search (1, 2) suggests that the usual way to find a substring within a field is to use
$regex
. If so, and you have a user-entered string (which might contain characters that have special meaning to$regex
), you’ll want to escape them. So for instance:…where
escapeRegex
is from that linked question’s answers. (Apparently JavaScript regular expression objects are supported, as well as strings using PCRE syntax instead.)If for some reason you can’t do that, you can also pass a string for
$where
, so you could create the string dynamically:Normally, writing JavaScript code in strings is a bad idea (even though Mongoose has to convert whatever function you give it to a string to send it to the server anyway), but if you need to do this kind of substitution…