Отображение имеет много связей в массиве элементов либо в postgres, либо в objection.js. - PullRequest
0 голосов
/ 12 января 2019

У меня есть база данных postgres, и я использую Knex с Objection.js. Это может быть проблема, связанная с postgres, или проблема objection.js / knex.

У меня есть две модели: учетная запись и статистика. Учетная запись имеет поле «accountId» и Stat также имеет поле «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 голосов
/ 12 января 2019

Стучал по голове часами, и после публикации я нашел одно решение, используя нетерпеливый метод Objection.js:

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

Небольшая проблема заключается в том, что он фактически выполняет два отдельных запроса. Я думаю, что нет способа сделать это с помощью одного запроса на Objection.js? Но есть ли способ использовать postgres для этой работы?

...