0

Documents are stored with regex, like

{
  "id": "id-1",
  "blocked": [
    "abcd.com/[a-z]+",
    "efgh.com/[0-9]+"
  ]
},
{
  "id": "id-2",
  "blocked": [
    "pqrs.com/[\w]+",
    "xyz.com/[.]+"
  ]
}

Basically I am looking how to query against the stored regex.

Case 1: If I pass "abcd.com/mongodb" then it mataches with the first document. So query should retrun first document

Case 2: If I pass "google.com/mongo" then it does not match with any stored regex. So query should return empty array.

4
  • Does this answer your question? Converting user input string to regular expression Commented Sep 28, 2020 at 13:59
  • it might not work, If i convert my input to regex, \abcd.com\mongodb\$ then it will not match with text abcd.com/[a-z]+ Commented Sep 28, 2020 at 14:04
  • You mean the other way? abcd.com/[a-z]+ won't match \abcd.com\mongodb\$? Well maybe your regexp is wrong... I don't really understand your problem here. If you want to convert a string to a regex, use the constructor new RegExp() and it does the job. Right? Commented Sep 28, 2020 at 14:17
  • 1
    @sjahan Thanks for supporting. Usually we store text in the document and query using $regex which will be supplied. But this scenario is bit different. Here we stored some regex, and I have text which will be supplied. Now I want to return the documents which satisfy the matches. It is like reverse regex. Commented Sep 28, 2020 at 14:24

2 Answers 2

1
//MongoDB version on windows(actual code output from mongo shell 4.2 on windows)
> db.version();
4.2.6
//prepare the same data and query it as below, per problem statement
> db.test5.find()
{ "_id" : ObjectId("5f721b8a3d04e9033d482a9b"), "id" : "id-1", "blocked" : [ "abcd.com/[a-z]+", "efgh.com/[0-9]+" ] }
{ "_id" : ObjectId("5f721b8a3d04e9033d482a9c"), "id" : "id-2", "blocked" : [ "pqrs.com/[w]+", "xyz.com/[.]+" ] }
declare variables to include the string for which regex can be checked from collection
> var1 = "abcd.com/mongodb";
abcd.com/mongodb
> var2 = "google.com/mongo";
google.com/mongo
//actual code output from mongo shell using aggregate
//you need to use $regexMatch to match the variable string to that is stored in the collection
> db.test5.aggregate([
... {$unwind:"$blocked"},
... {$addFields:{result1:{$regexMatch:{input:var1,regex:"$blocked"}}}},
... {$addFields:{result2:{$regexMatch:{input:var2,regex:"$blocked"}}}}
... ]);
{ "_id" : ObjectId("5f721b8a3d04e9033d482a9b"), "id" : "id-1", "blocked" : "abcd.com/[a-z]+", "result1" : true, "result2" : false }
{ "_id" : ObjectId("5f721b8a3d04e9033d482a9b"), "id" : "id-1", "blocked" : "efgh.com/[0-9]+", "result1" : false, "result2" : false }
{ "_id" : ObjectId("5f721b8a3d04e9033d482a9c"), "id" : "id-2", "blocked" : "pqrs.com/[w]+", "result1" : false, "result2" : false }
{ "_id" : ObjectId("5f721b8a3d04e9033d482a9c"), "id" : "id-2", "blocked" : "xyz.com/[.]+", "result1" : false, "result2" : false }
>
//the result will be true or false boolean.
//Hope, you can use this result to process your further logic of return array or empty string
//eg. case1 per your requirements: Since var1 matches with string it matches to true
//similarly case2 per your requirements: Since var2 does not match it returns false
Sign up to request clarification or add additional context in comments.

Comments

0

Not sure I totally get your problem, but here is a quick attempt to solve what I think I got!

Feel free to comment. It is not optimized: creating new RegExp every iteration is probably not the best idea, just simpler to implement!

const documents = [{
  "id": "id-1",
  "blocked": [
    "abcd.com/[a-z]+",
    "efgh.com/[0-9]+"
  ]
},
{
  "id": "id-2",
  "blocked": [
    "pqrs.com/[\w]+",
    "xyz.com/[.]+"
  ]
}];

const inputs = ["abcd.com/mongodb", "google.com/mongo"];

function check(input) {
  documents.forEach(document => {
    const matchFound = document.blocked.some(regexp => new RegExp(regexp).test(input));
    if(matchFound) {
      console.log(`Input '${input} matched document ${document.id}'`);
    }
  });
}

inputs.forEach(check);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.