Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to escape `$like` wildcard characters `%` and `_` in sequelize?

How does one tell sequelize (using sqlite3) to escape wildcard characters (%,_) in a $like clause?

For example, I'd like to generate a query comparable to the one below which finds the literal string _cool_ in any "things.description" (not just the word "cool" surrounded by any characters):

SELECT * FROM things WHERE description LIKE '\_cool\_' ESCAPE '\';  

I'm guessing it would look something like this but the resulting query is not what I would hope:

Thing.findAll({
  where: {
    description: {
      $like: ['?', '_cool_'],
      // ... or ...
      $like: '\\_cool\\_',
      $escape: '\\',
    }
  }
});

// => Executing (default):
// SELECT `id`, `description`
//   FROM `Things` AS `Thing`
//   WHERE `Thing`.`description` LIKE '?','_cool_';

Unfortunately I cannot drop into a raw query because the "LIKE" clause will be part of a larger dynamic query.

Any ideas?

like image 205
maerics Avatar asked Oct 24 '25 21:10

maerics


1 Answers

A full solution based on @piotrbienias that takes any user input and properly escapes it -

if (typeof query.string !== 'string') {
    throw Error('expecting string')
}
const inputRaw = query.string.replace(/(_|%|\\)/g, '\\$1');
const inputSec = sequelize.escape(`%${inputRaw}%`);
description = {
    $like: sequelize.literal(`${inputSec} ESCAPE '\\'`)
};

For the example string _cool_ this will translate to -

LIKE '%\\_cool\\_%' ESCAPE '\\'

You can change the logic to add other wildcards depending on your actual use case

if your using mysql and not sqlite the default escape is anyway \ so the ESCAPE declaration can be removed

like image 187
Yoni Jah Avatar answered Oct 26 '25 11:10

Yoni Jah