skip to Main Content

I am attempting to combine two regex operators when querying my MongoDB, the second of which (id) being a number field, hence the weird conversions.

Both of these work individually, and if I replace the $where regex with a more traditional one, it also works, however when run as is, it only looks for records that match the $where regex

this.Asset
  .find(query)
  .or([
        {
          name: { $regex: searchQuery, $options: "i" }
        },
        {
          $where: `function() { return this.id.toString().match(${searchQuery}) != null; }`
        }
    ])

2

Answers


  1. Did you try

    this.id.toString().match(${searchQuery}) != null || this.name.match(${searchQuery})
    ?

    Login or Signup to reply.
  2. I didn’t try to debug the issue with $where because it is best to avoid using it if at all possible. The performance characteristics of using it really are not good for usage in production environments.

    Instead, you can accomplish what you want via conversion operators in MongoDB directly. The $toString operator is particularly relevant here. Assuming that searchQuery is "123", one approach would be as follows:

    db.collection.find({
      $or: [
        {
          name: {
            $regex: "123",
            $options: "i"
          }
        },
        {
          $expr: {
            $regexMatch: {
              input: {
                $toString: "$id"
              },
              regex: "123",
              options: "i"
            }
          }
        }
      ]
    })
    

    Playground demonstration here. Alternatively:

    db.collection.aggregate([
      {
        $addFields: {
          idConverted: {
            $toString: "$id"
          }
        }
      },
      {
        $match: {
          $or: [
            {
              name: {
                $regex: "123",
                $options: "i"
              }
            },
            {
              idConverted: {
                $regex: "123",
                $options: "i"
              }
            }
          ]
        }
      },
      {
        $unset: "idConverted"
      }
    ])
    

    demo here.

    That said, even these approaches that avoid using $where are unlikely to be performant. Queries that filter on the transformed results are unable to use indexes efficiently. You may wish to look into other text searching approaches entirely for this to be usable by a production application.

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