使用Knex对我的Postgres数据库进行查询。我有一个使用Knex QueryBuilder提供“基本”查询的函数。在我需要向SELECT语句中添加原始内容之前,此方法可以正常工作。据我所知,运行.raw
总是要返回结果。不过,我只需要将其添加到QueryBuilder中,以便可以由我的应用程序的不同部分执行它。
const baseQuery = knex
.select(newUserFields)
.from('users')
.leftJoin('user_roles', 'users.id', 'user_roles.user_id')
.leftJoin('roles', 'user_roles.role_id', 'roles.id')
.leftJoin('role_permissions', 'roles.id', 'role_permissions.role_id')
.leftJoin(
'permissions',
'permissions.id',
'role_permissions.permission_id'
)
.groupBy(
'users.id',
'users.email',
'users.name',
'users.status',
'users.created_at',
'users.password_reset_expiration',
'users.password',
'users.password_reset_token'
)
.orderBy('users.created_at', 'desc');
我需要在选择项中添加以下内容:
knex.raw('to_json(array_agg(distinct roles.name)) as roleNames')
knex.raw('to_json(array_agg(distinct permissions.name)) as permissionNames')
如何将这些原始选择添加到基本查询中,然后可以将基本查询作为QueryBuilder
传递给其他函数并添加到其中?
答案 0 :(得分:1)
关于knex
的一件很酷的事情是它是一个 queryBuilder ,它使您可以调用方法而不受调用顺序的任何限制。这意味着您可以只在函数中构造基本查询,然后将附加的内容(例如附加的列)附加到该查询上。
根据您的情况,您可以再打一次电话来选择(knex将加入选择呼叫)
// base-query.js
export const getBaseQuery = () => knex
.select(newUserFields)
.from('users')
.leftJoin('user_roles', 'users.id', 'user_roles.user_id')
.leftJoin('roles', 'user_roles.role_id', 'roles.id')
.leftJoin('role_permissions', 'roles.id', 'role_permissions.role_id')
.leftJoin('permissions', 'permissions.id', 'role_permissions.permission_id')
.groupBy(
'users.id',
'users.email',
'users.name',
'users.status',
'users.created_at',
'users.password_reset_expiration',
'users.password',
'users.password_reset_token'
)
.orderBy('users.created_at', 'desc');
// other-file.js
import {getBaseQuery} from 'base-query';
const enhancedQuery = getBaseQuery().select([
knex.raw('to_json(array_agg(distinct roles.name)) as roleNames'),
knex.raw('to_json(array_agg(distinct permissions.name)) as permissionNames'),
]);
const results = await enhancedQuery;
我正在大量使用的另一种很酷的方法可以满足以下要求:有时我需要从外部更改内部查询,我使用modify
例如,我有一个getProducts
方法,该方法执行一个select
查询并进行一些数据转换。
为了实现getProductById
,它需要返回相同的数据结构(只需要过滤基本查询),我传递了一个queryModifier方法,该方法修改了原始查询。
async function getProducts(queryModifier) {
const products = await knex
.select('*')
.from('products')
.modify((queryBuilder) => {
if (typeof queryModifier === 'function') {
return queryModifier(queryBuilder);
}
});
return products.map(someDataTransformation);
}
async function getProductById(id) {
return getProducts((qb) => {
return qb.where('id', id);
});
}