使用具有多个搜索条件的 Knex.js 和 SQL 的条件过滤器

Posted

技术标签:

【中文标题】使用具有多个搜索条件的 Knex.js 和 SQL 的条件过滤器【英文标题】:Conditional filter using Knex.js and SQL with multiple search criteria 【发布时间】:2016-10-05 11:31:44 【问题描述】:

我有一个用户需要能够搜索的项目数据库。他们可以应用不同的过滤器,例如categorysearchTermitemType

我知道如何在 knex 查询中应用这些过滤器,但不确定如何有条件地组合它们。例如。在一种情况下,用户只输入 searchTerm。所以我不想按类别或项目类型过滤,而只想按 searchTerm。但是,我只想有一个 knex 函数,它有条件地向查询中添加额外的子句。

类似:

const getFilteredItems = (searchCriteria) => knex('items')
   // IF (searchCriteria.searchTerm)
  .where('items.itemName', 'like', `%$searchCriteria.searchTerm%`)
  // IF (searchCriteria.itemType)
  .where('items.itemType', '=', searchCriteria.itemType)
  // IF (searchCriteria.category)
  .where('items.category', '=', searchCriteria.category)

但我不确定如何有条件地将额外的 where 子句附加到 knex 查询中。有没有一种无需编写原始 SQL 的优雅方法?

【问题讨论】:

【参考方案1】:

您可以使用 knex 查询构建器有条件地构建您的查询:

const getFilteredItems = (searchCriteria) => knex('items')
  .where((qb) => 
    if (searchCriteria.searchTerm) 
      qb.where('items.itemName', 'like', `%$searchCriteria.searchTerm%`);
    

    if (searchCriteria.itemType) 
      qb.orWhere('items.itemType', '=', searchCriteria.itemType);
    

    if (searchCriteria.category) 
      qb.orWhere('items.category', '=', searchCriteria.category);
    
  );

您也可以使用this,而不是像@abdulbarik 给出的示例那样接受querybuilder 参数,但我认为它不太明确。

【讨论】:

注意箭头函数使用父函数的this绑定。如果您想使用this 而不是接受 QueryBuilder 参数,它必须是常规函数。【参考方案2】:

您可以尝试以下方法:

const getFilteredItems = (searchCriteria) => knex('items')
  .where('items.itemName', 'like', `%$searchCriteria.searchTerm || ''%`)
  .where('items.itemType', 'like', `%$searchCriteria.itemType || ''%`)
  .where('items.category', 'like', `%$searchCriteria.category || ''%`)

如果缺少任何参数或undefined,它将匹配该字段为'%%',这实际上意味着,不要关心这个参数。

【讨论】:

【参考方案3】:

尝试orWhere 并在此基础上更新您的查询

const getFilteredItems = (searchCriteria) => knex('items')
   // IF (searchCriteria.searchTerm)
  .where('items.itemName', 'like', `%$searchCriteria.searchTerm%`)
  // IF (searchCriteria.itemType)
  .orWhere('items.itemType', '=', searchCriteria.itemType)
  // IF (searchCriteria.category)
  .orWhere('items.category', '=', searchCriteria.category)

示例

knex('users').where(function() 
  this.where('id', 1).orWhere('id', '>', 10)
).orWhere(name: 'Tester')

【讨论】:

【参考方案4】:

您可以通过这样的异步等待函数使其变得简单:

public async getFilteredItems(searchCriteria): Promise<any[]> 
    const table = 'items';
    const columns = ['itemName', 'itemType', 'category'];
    const qb = (query) => 
      for (const col of columns) 
        query.orWhere(`$table.$col`, 'like', `%$searchCriteria[col]%`);
      
    
    return await knex(table).where(qb);

【讨论】:

以上是关于使用具有多个搜索条件的 Knex.js 和 SQL 的条件过滤器的主要内容,如果未能解决你的问题,请参考以下文章

Knex.js 会阻止 sql 注入吗?

Knex.js:加入 'select' 和 'where' 子句

在T-SQL中具有可变数量的搜索条件的LIKE运算符

在 Node 应用程序中使用 AND 使用 Knex.js 构造内部连接

尝试使用 Knex.js 构建查询以获取两个月之间的行数

SQL Server SUM IF 使用具有多个条件的窗口函数