我如何在没有两个查询的情况下在 Knex 中执行此操作
How can I do this in Knex without two queries
我想在不使用两个查询的情况下进行此搜索:
app.db('users').where({
id: req.userData.id
}).first().then(result => {
if (!result) {
throw new CompleteError('Usuário não encontrado.', 404)
}
app.db('addresses').where({
id: result.address_id
}).first().then(address_result => {
if (address_result) {
result.address = address_result
res.json(result)
} else {
throw new CompleteError('Falha ao buscar endereço do usuário.', 500)
}
}).catch(e => {
return next(e)
})
}).catch(e => {
return next(e)
})
如果其中一项搜索失败或未找到任何寄存器,则搜索进程停止并抛出错误。数据库是postgresql。如果没有其他方法可以替代此方法,请帮助改进此代码,我是初学者开发人员,我需要您的意见。拜托,对不起我的英语。
结果必须是这样的:
{
"id": 21,
"name": "Sérgio",
"cpf": "11111111111",
"email": "sergio11@gmail.com",
"pass": "a$Jx7wAd3QSMFlkXi3g0eVOOoW8o65OgDZVQ7wTWuxquytVhUhrUf/.",
"phone": "5544313113131",
"last_access": "2020-08-11T10:14:20.207Z",
"created_at": "2020-08-11T10:14:20.207Z",
"deleted_at": null,
"address_id": 21,
"address": {
"id": 21,
"street": "Street Manu",
"number": "851",
"complement": "A",
"city": "Mari Hill",
"state": "Para",
"country": "Brazil",
"last_access": "2020-08-11T10:14:19.837Z",
"created_at": "2020-08-11T10:14:19.837Z",
"deleted_at": null
}
}
您可以使用 JOIN 执行此查询,然后执行一些 re-arranging 结果。
您正在寻找的查询看起来像这样:
SELECT *
FROM users
LEFT JOIN addresses ON addresses.id=users.address_id;
(我比较熟悉MySQL/MariaDB所以语法可能有点不同)。
LEFT JOIN
表示如果找到用户但未找到地址,地址列将为空。
这可以翻译成以下 Knex 表达式:
app.db('users')
.leftJoin('addresses', 'addresses.id', '=', 'users.address_id')
.select(
'users.id',
'users.name',
'users.cpf',
'users.email',
'users.pass',
'users.phone',
'users.last_access',
'users.created_at',
'users.deleted_at',
'users.address_id',
'addresses.id AS addr_id',
'addresses.street AS addr_street',
'addresses.number AS addr_number',
'addresses.complement AS addr_complement',
'addresses.city AS addr_city',
'addresses.state AS addr_state',
'addresses.country AS addr_country',
'addresses.last_access AS addr_last_access',
'addresses.created_at AS addr_created_at',
'addresses.deleted_at AS addr_deleted_at'
)
.first()
.then((result) => {
// no result at all? no user found
if (!result) {
throw new CompleteError('Usuário não encontrado.', 404);
}
// no addr_id? user found but not the address
if (!result.addr_id) {
throw new CompleteError('Falha ao buscar endereço do usuário.', 500);
}
// result contains all the fields from BOTH tables as a flat object
// you'll need to rearrange things
return {
// assign properties to new names...
id: result.id,
// and so on...
};
});
请注意,我在 select()
调用中重命名了来自 addresses
的所有列。这是因为 Knex 不会在带有 JOIN
子句的查询中分配新的列名,除非您明确命名这些列,否则您最终会得到重复的列名(以及很多混淆)。
我想在不使用两个查询的情况下进行此搜索:
app.db('users').where({
id: req.userData.id
}).first().then(result => {
if (!result) {
throw new CompleteError('Usuário não encontrado.', 404)
}
app.db('addresses').where({
id: result.address_id
}).first().then(address_result => {
if (address_result) {
result.address = address_result
res.json(result)
} else {
throw new CompleteError('Falha ao buscar endereço do usuário.', 500)
}
}).catch(e => {
return next(e)
})
}).catch(e => {
return next(e)
})
如果其中一项搜索失败或未找到任何寄存器,则搜索进程停止并抛出错误。数据库是postgresql。如果没有其他方法可以替代此方法,请帮助改进此代码,我是初学者开发人员,我需要您的意见。拜托,对不起我的英语。
结果必须是这样的:
{
"id": 21,
"name": "Sérgio",
"cpf": "11111111111",
"email": "sergio11@gmail.com",
"pass": "a$Jx7wAd3QSMFlkXi3g0eVOOoW8o65OgDZVQ7wTWuxquytVhUhrUf/.",
"phone": "5544313113131",
"last_access": "2020-08-11T10:14:20.207Z",
"created_at": "2020-08-11T10:14:20.207Z",
"deleted_at": null,
"address_id": 21,
"address": {
"id": 21,
"street": "Street Manu",
"number": "851",
"complement": "A",
"city": "Mari Hill",
"state": "Para",
"country": "Brazil",
"last_access": "2020-08-11T10:14:19.837Z",
"created_at": "2020-08-11T10:14:19.837Z",
"deleted_at": null
}
}
您可以使用 JOIN 执行此查询,然后执行一些 re-arranging 结果。
您正在寻找的查询看起来像这样:
SELECT *
FROM users
LEFT JOIN addresses ON addresses.id=users.address_id;
(我比较熟悉MySQL/MariaDB所以语法可能有点不同)。
LEFT JOIN
表示如果找到用户但未找到地址,地址列将为空。
这可以翻译成以下 Knex 表达式:
app.db('users')
.leftJoin('addresses', 'addresses.id', '=', 'users.address_id')
.select(
'users.id',
'users.name',
'users.cpf',
'users.email',
'users.pass',
'users.phone',
'users.last_access',
'users.created_at',
'users.deleted_at',
'users.address_id',
'addresses.id AS addr_id',
'addresses.street AS addr_street',
'addresses.number AS addr_number',
'addresses.complement AS addr_complement',
'addresses.city AS addr_city',
'addresses.state AS addr_state',
'addresses.country AS addr_country',
'addresses.last_access AS addr_last_access',
'addresses.created_at AS addr_created_at',
'addresses.deleted_at AS addr_deleted_at'
)
.first()
.then((result) => {
// no result at all? no user found
if (!result) {
throw new CompleteError('Usuário não encontrado.', 404);
}
// no addr_id? user found but not the address
if (!result.addr_id) {
throw new CompleteError('Falha ao buscar endereço do usuário.', 500);
}
// result contains all the fields from BOTH tables as a flat object
// you'll need to rearrange things
return {
// assign properties to new names...
id: result.id,
// and so on...
};
});
请注意,我在 select()
调用中重命名了来自 addresses
的所有列。这是因为 Knex 不会在带有 JOIN
子句的查询中分配新的列名,除非您明确命名这些列,否则您最终会得到重复的列名(以及很多混淆)。