I have created an API using Express in NodeJS which is using NeDB for its database.
I have examined the documentation and I can see that there is a way to filter results using regular expressions in order to carry out operations similar to "like" in SQL.
I am able to get the regular expressions to work when creating a hardcoded JSON object to use as the filter but when a filter is passed via my API, NeDB reports the following error:
Error: $regex operator called with non regular expression
My test database contains the following documents:
[
{
"test": "Hello",
"other": "Goodbye",
"_id": "9T0WaZ240q6ZK747"
},
{
"test": "sup!",
"other": "Ta ta",
"extra": "something",
"_id": "jLUzEZjLDVX1lmU5"
}
]
When I execute a find()
on the data using a hardcoded JSON filter it will return the correct result e.g.
{
test: {
$regex: /hell/i
}
}
will return the first record in the database.
However, when I call the find()
function from my API where I am passing the JSON object filter across, I receive the error mentioned before.
The filter from my API gets added as follows:
{ test: { '$regex': '/hell/i' } }
It looks like it may be the single quotes that are causing some issues but even after stripping them out it does not work. Either I get the same error or some other JSON parsing error.
I examined the code for NeDB and in the model.js
file I added a line to print to the console what regular expression it had detected. In both cases (the hardcoded method that worked and the API method) the regular expression was returned as:
/hell/i
So it seems that NeDB is receiving an identical expression for both calls but for some reason throws an error with the API method.
Has anyone tried passing a JSON filter to an NeDB instance using the find()
method and have it filter successfully?
I am using Postman for my API testing.
I have now managed to work out a sort-of solution. This is by no means perfect and still requires some more work and testing.
I ended up modifying the model.js
file within NeDB, more specifically the comparisonFunctions.$regex
function. I added an additional check to see if the regular expression that gets passed in can be converted to a regular expression from its string form. The model.js
file now looks as follows:
comparisonFunctions.$regex = function (a, b) {
if (!util.isRegExp(b)) {
try {
// convert the string based regex into an actual regular expression
b = new RegExp(b.replace(/[\\/]/g, ""), 'i');
// check again if it worked
if (!util.isRegExp(b))
throw new Error("$regex operator called with non regular expression");
} catch {
// we were not working with a regex
throw new Error("$regex operator called with non regular expression");
}
}
if (typeof a !== 'string') {
return false
} else {
return b.test(a);
}
};
So now if I pass this to my API:
{
"test": {
"$regex": "/ell/"
}
}
It will return the first document from the database where the test
field == Hello
Any recommendations on how to make this neater and/or feedback will be greatly appreciated.