Search code examples
postgresqlknex.js

How to use bindings in a whereRaw query?


I have a table with two columns, 'first_name' and 'last_name' and I want to join both tables so that I can search a query against them with a LIKE query and using % wildcards.

I was able to do this when I used a string literal, however it is not working when I'm trying to use positional bindings. I am returned with nothing.

Is there a way to join the two columns without concat and a whereRaw function? And how would I write the binding correctly?

const searchUser = (query) => {
  const name = query.toLowerCase();
  return knex('users')
    .select('*')
    .whereRaw('concat(LOWER("first_name"), \' \' , LOWER("last_name")) LIKE \'%??%\'', [name]);
};

Solution

  • It appears that you may be trying to query two separate columns with the same value?

    What you could do here is a orWhere chain which links multiple where statements together where it matches if just one is true.

    For example:

    const searchUser = (query) => {
      return knex('users')
        .select('*')
        .where(knex.raw('first_name ILIKE ?', `%${query}%`))
        .orWhere(knex.raw('last_name ILIKE ?', `%${query}%`));
    };
    

    This also uses "ILIKE" which gets you the same case insensitive matching that you're achieving with the LOWER function.

    You may also find value using a named binding rather than positional bindings. This would look like this:

    const searchUser = (query) => {
      const bindings = { query: `%${query}%` };
      return knex('users')
        .select('*')
        .where(knex.raw('first_name ILIKE :query', bindings))
        .orWhere(knex.raw('last_name ILIKE :query', bindings));
    };