skip to Main Content

I have a nodejs express web with a mongo db with

const AuthorSchema = new Schema({
    first_name: { type: String, required: true, maxLength: 100 },
    family_name: { type: String, required: true, maxLength: 100 },
    date_of_birth: { type: Date },
    date_of_death: { type: Date },
});

I want to search for an author using a regexp over the first_name + family_name. In other words,
given we have an author with:

first_name: ‘Alessandro’
family_name: ‘Manzoni’

I want to match it using all of the search strings:

‘Alessandro’ or ‘ale’ or ‘manzo’ or ‘alessandro manzoni’ or ‘Manzoni Alessandro’

so I wrote this:

const searchRegex = new RegExp(req.body.search_text, 'i');  
Author.find({ $where: 
    function() {
        return (searchRegex.test(this.first_name + " " + this.family_name) 
            || searchRegex.test(this.family_name + " " + this.first_name) )
    } 
},"_id").exec(function (err, list_authors) {

and I got:

MongoServerError: Executor error during find command :: caused by :: ReferenceError: searchRegex is not defined :
@:2:33

I tried using a $let clause but all I’ve achieved is getting all of the authors id in the results list.

2

Answers


  1. Chosen as BEST ANSWER

    Thanks, your answer works perfectly. I added a $or to search also in family_name + " " + first_name and deleted the options line because they are in the regex. So the final code is:

    Author.find({
      $or: [
        {
          "$expr": {
            "$eq": [
              {
                "$regexMatch": {
                  "input": {
                    "$concat": [
                      "$first_name",
                      " ",
                      "$family_name"
                    ]
                  },
                  "regex": searchRegex
                }
              },
            true
          ]
        }
      }, {
        "$expr": {
          "$eq": [
            {
              "$regexMatch": {
                "input": {
                  "$concat": [
                    "$family_name",
                    " ",
                    "$first_name"
                  ]
                },
                "regex": searchRegex
              }
            },
            true
          ]
        }
      },                    
    ]},"_id").exec(callback);
    

    Really a lot of code, but it works...


  2. I think you are looking for something like this (and avoiding $where which is very inefficient):

    This query get the first and family names concatenated and do the regex match on it.

    If there is a match in the regex (the result is true) the document will be returned. Otherwise it doesn’t.

    Author.find({
      "$expr": {
        "$eq": [
          {
            "$regexMatch": {
              "input": {
                "$concat": [
                  "$first_name",
                  " ",
                  "$family_name"
                ]
              },
              "regex": yourStringRegexHere,
              "options": "i"
            }
          },
          true
        ]
      }
    })
    

    Example here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search