【问题标题】:How can I do this in Knex without two queries如何在没有两个查询的情况下在 Knex 中执行此操作
【发布时间】:2020-08-13 02:30:44
【问题描述】:

我想在不使用两个查询的情况下进行此搜索:

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": "$2a$10$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
  }
}

【问题讨论】:

    标签: node.js postgresql knex.js


    【解决方案1】:

    您可以使用 JOIN 执行此查询,然后重新排列结果。

    您要查找的查询如下所示:

    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 子句的查询中分配新的列名,除非您明确命名列,否则您将得到重复的列名(并且会造成很多混乱)。

    【讨论】:

      猜你喜欢
      • 2015-02-12
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 2012-03-25
      • 1970-01-01
      • 2015-09-28
      • 1970-01-01
      • 2016-07-13
      相关资源
      最近更新 更多