【问题标题】:Conditional filter using Knex.js and SQL with multiple search criteria使用具有多个搜索条件的 Knex.js 和 SQL 的条件过滤器
【发布时间】: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 的优雅方法?

【问题讨论】:

    标签: javascript sql node.js knex.js


    【解决方案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);
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-08
          • 1970-01-01
          • 1970-01-01
          • 2019-10-10
          • 2013-01-18
          • 2012-02-12
          • 2015-12-06
          • 2020-04-17
          相关资源
          最近更新 更多