映射与postgres或objection.js

时间:2019-01-12 18:04:48

标签: postgresql knex.js objection.js

我有一个postgres数据库,并且正在将Knex与Objection.js一起使用。这可能是与postgres相关或与objection.js / knex相关的问题。

我有两个模型,帐户和统计。帐户的字段为“ accountId”,统计信息的字段也为“ accountId”。一个帐户可以有多个统计信息。

Account:
╔════════════╦═════════════╗
║ accountId  ║ title       ║
╠════════════╬═════════════╣
║ a          ║ Account 1   ║
║ b          ║ Account 2   ║
╚════════════╩═════════════╝
Stat:
╔════════════╦════════════╦═════════════╗
║ accountId  ║ subs       ║ month       ║
╠════════════╬════════════╬═════════════╣
║ a          ║ 313        ║ 2019/01     ║
║ b          ║ 30         ║ 2019/01     ║
║ a          ║ 909        ║ 2019/02     ║
║ a          ║ 100        ║ 2019/03     ║
║ b          ║ 3          ║ 2019/02     ║
╚════════════╩════════════╩═════════════╝

我想获取一个包含其统计信息的帐户[以便将统计信息限制在某些月份之内]。

我有Objection.js查询:

Account.query()
        .select(['Accounts.*', 'stats.*'])
        .where('Accounts.accountId', accountId)
        .joinRelation('stats')

像这样打印sql:

select "Accounts".*, "stats".* from "Accounts" inner join "Stats" as "stats" on "stats"."accountlId" = "Accounts"."accountId" where "Accounts"."accountId" = 'a'

结果为:

[{
    accountId: a,
    title: 'Account 1',
    subs: 313,
    month: '2019/01',
},{
    accountId: a,
    title: 'Account 1',
    subs: 909,
    month: '2019/02',
},{
    accountId: a,
    title: 'Account 1',
    subs: 100,
    month: '2019/03',
}]

而我想要这样的结果:

{
    accountId: a,
    title: 'Account 1',
    stats: [{
        subs: 313,
        month: '2019/01'
    },{
        subs: 909,
        month: '2019/02'
    },{
        subs: 100,
        month: '2019/03'
    }]
}

我尝试使用postgres array_agg,但是不确定我是否正确理解了主体。在postgres级别是否可能发生这种情况,或者Objection.js应该以某种方式处理此问题?还是查询后在javascript中手动进行映射的唯一选择?

1 个答案:

答案 0 :(得分:0)

挣扎了好几个小时,发布之后,我发现了一个使用Objection.js eager方法的解决方案:

Account.query()
    .eager('stats')
    .modifyEager('stats', builder => {
      /*builder.where('month', '2019/01')*/
    })
    .select()
    .where('Accounts.accountId', accountId)
    .first()

这里的一个小问题是它实际上执行两个单独的查询。我想没有办法通过对Objection.js的单个查询来做到这一点?但是有什么方法可以利用postgres完成这项工作吗?