首页 > 解决方案 > 使用 knex.js 进行模式匹配

问题描述

我有以下查询:

const result = await knex('Words')
  .leftJoin('Active', 'Words.Column', '=', 'Active.Column')
  .leftJoin('Online', 'Words.Column', '=', 'Online.Column')
  .column(['Words.Column', 'TranslationEng'])
  .whereIn('Words.Column', sentenceArray);

最后一行的简短描述:来自输入框的sentenceArray (例如: ['Hello there', 'Hi'] )与我的 postgres-DB 中的数据相匹配,即Words.Column(例如: '你好'和'你好')。

我现在的问题:sentenceArray 可能并不总是与我的数据库中的单词匹配。我想我需要在 .leftJoin 和 .whereIn 中添加模式匹配。

目标是查询是:

  1. 不区分大小写
  2. 像 * 这样的符号被忽略
  3. 括号中的单词被忽略。

示例: sentenceArray: [ 'Hello (Denis)*', 'HI' ] => 应该匹配:'hello', 'hi' 在我的数据库中。

我已经尝试使用“like/ilike”来区分大小写,并尝试了几种组合,例如:

.leftJoin("Active", "Words.Column", "like", "%${Active.Column}%")

...但没有任何效果。有人能帮我吗?

标签: javascriptregexknex.js

解决方案


SQLin语句会查找整个单词,就像or操作的语法糖一样。

您需要的是使用like带有 wild char 的运算符%

目标查询应如下所示:

SELECT words.COLUMN, 
       translationeng 
FROM   words 
       LEFT JOIN active 
              ON active.COLUMN = words.COLUMN 
       LEFT JOIN online 
              ON online.COLUMN = words.COLUMN 
WHERE  words.COLUMN LIKE '%first-word%' 
        OR words.COLUMN LIKE '%second-word%'  ...

可以使用以下方式构建此查询knex

const result = await knex('Words')
  .leftJoin('Active', 'Words.Column', '=', 'Active.Column')
  .leftJoin('Online', 'Words.Column', '=', 'Online.Column')
  .column(['Words.Column', 'TranslationEng'])
  .where((qb) => {
    sentenceArray.forEach((word) => qb.whereOr('Words.Column', 'like', `%${word}%`));
    return qb;
  });

编辑:

const result = await knex('Words')
  .leftJoin('Active', 'Words.Column', '=', 'Active.Column')
  .leftJoin('Online', 'Words.Column', '=', 'Online.Column')
  .column(['Words.Column', 'TranslationEng'])
  .where((qb) => {
    sentenceArray.forEach((word) =>
      qb.whereOr('Words.Column', 'like', `%${word.replace(/\W+/g, '%')}%`)
    );
    return qb;
  });

推荐阅读