使用具有多个搜索条件的 Knex.js 和 SQL 的条件过滤器
Conditional filter using Knex.js and SQL with multiple search criteria
我有一个项目数据库,我的用户需要能够搜索这些项目。他们可以应用不同的过滤器,例如 category
、searchTerm
、itemType
。
我知道如何在 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 的情况下做到这一点?
尝试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'})
您可以尝试以下方法:
const getFilteredItems = (searchCriteria) => knex('items')
.where('items.itemName', 'like', `%${searchCriteria.searchTerm || ''}%`)
.where('items.itemType', 'like', `%${searchCriteria.itemType || ''}%`)
.where('items.category', 'like', `%${searchCriteria.category || ''}%`)
如果缺少任何参数或undefined
,它将匹配字段,如'%%'
,这实际上意味着,不关心这个参数。
您可以使用 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 参数,但我认为它不太明确。
您可以像这样使用异步等待函数使其变得简单:
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);
}
我有一个项目数据库,我的用户需要能够搜索这些项目。他们可以应用不同的过滤器,例如 category
、searchTerm
、itemType
。
我知道如何在 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 的情况下做到这一点?
尝试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'})
您可以尝试以下方法:
const getFilteredItems = (searchCriteria) => knex('items')
.where('items.itemName', 'like', `%${searchCriteria.searchTerm || ''}%`)
.where('items.itemType', 'like', `%${searchCriteria.itemType || ''}%`)
.where('items.category', 'like', `%${searchCriteria.category || ''}%`)
如果缺少任何参数或undefined
,它将匹配字段,如'%%'
,这实际上意味着,不关心这个参数。
您可以使用 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 参数,但我认为它不太明确。
您可以像这样使用异步等待函数使其变得简单:
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);
}