Knex.js 多个 orderBy() 列
Knex.js multiple orderBy() columns
是否可以执行多个 orderBy() 列?
knex
.select()
.table('products')
.orderBy('id', 'asc')
可链接的 orderBy() 仅采用单列键和排序值,但我如何按多列排序?
您可以call .orderBy
multiple times按多列排序:
knex
.select()
.table('products')
.orderBy('name', 'desc')
.orderBy('id', 'asc')
最初的答案在技术上是正确的,而且很有用,但我的目的是找到一种以编程方式多次应用 orderBy()
函数的方法,这里是我参考的实际解决方案:
var sortArray = [
{'field': 'title', 'direction': 'asc'},
{'field': 'id', 'direction': 'desc'}
];
knex
.select()
.table('products')
.modify(function(queryBuilder) {
_.each(sortArray, function(sort) {
queryBuilder.orderBy(sort.field, sort.direction);
});
})
Knex提供修改功能,可以直接操作queryBuilder。然后数组迭代器多次调用 orderBy()
。
您可以使用以下解决方案来解决您的问题:
const builder = knex.table('products');
sortArray.forEach(
({ field, direction }) => builder.orderBy(field, direction)
);
Knex orderBy 函数也接收一个数组:
knex('users').orderBy(['email', 'age', 'name'])
或
knex('users').orderBy(['email', { column: 'age', order: 'desc' }])
或
knex('users').orderBy([{ column: 'email' }, { column: 'age', order: 'desc' }])
orderBy
接受类型数组:
[
{column: 'id', order: 'asc'},
{column: 'name', order: 'desc'},
{column: 'created_at', order: 'desc'},
]
我有一个从请求中获取参数的函数:
sort=id,name,-created_at
并构建一个传递给 queryBuilder
的数组
columns
是一个数组,接受的值为 table 列
sort(model, sorts, columns) {
let confirmed = true;
sorts = sorts.split(',')
sorts.forEach((sort: string) => {
sort = sort.replace('-', '')
sort = sort.replace(' ', '')
confirmed = columns.includes(sort)
if (!confirmed) {
let index = sorts.indexOf(sort)
sorts.splice(index, 1)
}
})
let sortsArr = [];
sorts.forEach((sort) => {
if (sort.startsWith('-')) {
sort = sort.replace('-', '')
sortsArr.push({column: model.tableName + '.' + sort, order: 'desc'})
} else {
sortsArr.push({column: model.tableName + '.' + sort, order: 'asc'})
}
})
return sortsArr;
}
然后在查询中像这样使用它
const sortsArr = sort(model, sorts, model.columns);
knex('users').orderBy(sortsArr)
是否可以执行多个 orderBy() 列?
knex
.select()
.table('products')
.orderBy('id', 'asc')
可链接的 orderBy() 仅采用单列键和排序值,但我如何按多列排序?
您可以call .orderBy
multiple times按多列排序:
knex
.select()
.table('products')
.orderBy('name', 'desc')
.orderBy('id', 'asc')
最初的答案在技术上是正确的,而且很有用,但我的目的是找到一种以编程方式多次应用 orderBy()
函数的方法,这里是我参考的实际解决方案:
var sortArray = [
{'field': 'title', 'direction': 'asc'},
{'field': 'id', 'direction': 'desc'}
];
knex
.select()
.table('products')
.modify(function(queryBuilder) {
_.each(sortArray, function(sort) {
queryBuilder.orderBy(sort.field, sort.direction);
});
})
Knex提供修改功能,可以直接操作queryBuilder。然后数组迭代器多次调用 orderBy()
。
您可以使用以下解决方案来解决您的问题:
const builder = knex.table('products');
sortArray.forEach(
({ field, direction }) => builder.orderBy(field, direction)
);
Knex orderBy 函数也接收一个数组:
knex('users').orderBy(['email', 'age', 'name'])
或
knex('users').orderBy(['email', { column: 'age', order: 'desc' }])
或
knex('users').orderBy([{ column: 'email' }, { column: 'age', order: 'desc' }])
orderBy
接受类型数组:
[
{column: 'id', order: 'asc'},
{column: 'name', order: 'desc'},
{column: 'created_at', order: 'desc'},
]
我有一个从请求中获取参数的函数:
sort=id,name,-created_at
并构建一个传递给 queryBuilder
columns
是一个数组,接受的值为 table 列
sort(model, sorts, columns) {
let confirmed = true;
sorts = sorts.split(',')
sorts.forEach((sort: string) => {
sort = sort.replace('-', '')
sort = sort.replace(' ', '')
confirmed = columns.includes(sort)
if (!confirmed) {
let index = sorts.indexOf(sort)
sorts.splice(index, 1)
}
})
let sortsArr = [];
sorts.forEach((sort) => {
if (sort.startsWith('-')) {
sort = sort.replace('-', '')
sortsArr.push({column: model.tableName + '.' + sort, order: 'desc'})
} else {
sortsArr.push({column: model.tableName + '.' + sort, order: 'asc'})
}
})
return sortsArr;
}
然后在查询中像这样使用它
const sortsArr = sort(model, sorts, model.columns);
knex('users').orderBy(sortsArr)