Postgres:从数组获取json对象

时间:2019-11-11 17:35:34

标签: javascript node.js json postgresql node-postgres

我要返回{id: 'single-entry'}而不是[{Id:'single-entry'}]

我正在运行PostgreSQL v11.5

我在网上看了许多不同的示例,但是其中只有一行的数组不会变成json对象。

此查询中:

SELECT row_to_json(row)
FROM
(
    SELECT 
        t.*,
        json_agg(json_build_object('name', tr."name", 'id', r."remixTrackId")) 
        FILTER (WHERE tr."id" IS NOT NULL)
        AS remixes
    FROM "Tracks" t
        LEFT JOIN "Remixes" r ON r."originalTrackId" = t."id"
        LEFT JOIN "Tracks" tr ON tr."id" = r."remixTrackId"
    WHERE t."id" = '${trackId}'
    GROUP BY t."id"
) row;

我期望的是

{
  "id": "track-id2",
  "name": "My track 2",
  "dateModified": "2019-11-09T21:41:30.482634",
  "channels": {
    "some": "json"
  },
  "userId": 1,
  "remixes": null
}

我得到的是

[
  {
    "row_to_json": {
      "id": "track-id2",
      "name": "My track 2",
      "dateModified": "2019-11-09T21:41:30.482634",
      "channels": {
        "some": "json"
      },
      "userId": 1,
      "remixes": null
    }
  }
]

数据库连接和查询如下所示。 我正在使用运行Postgres的Node和Heroku

这是我如何执行查询的完整摘录:

const pg = require('pg')
const config = {
    user: 'xxx',
    database: 'xxx',
    password: 'xxx',
    port: 5432,
    ssl: true
};
const pool = new pg.Pool({ 
    connectionString: `postgres://${config.user}:${config.password}@xxx.amazonaws.com:5432/${config.database}`,
    ...config
})

app.get('/api/postgres/get-track', function(request, response) {
    const trackId = R.path(['query','id'], request)
    pool.connect(function(err, client, done) {
        if(err) {
            response.send("Could not connect to DB: " + err)
        } else {
            client.query(`
            SELECT row_to_json(row)
            FROM
            (
                SELECT 
                    t.*,
                    json_agg(json_build_object('name', tr."name", 'id', r."remixTrackId")) 
                    FILTER (WHERE tr."id" IS NOT NULL)
                    AS remixes
                FROM "Tracks" t
                    LEFT JOIN "Remixes" r ON r."originalTrackId" = t."id"
                    LEFT JOIN "Tracks" tr ON tr."id" = r."remixTrackId"
                WHERE t."id" = '${trackId}'
                GROUP BY t."id"
            ) row;
            `, function(err, result) {
                done()
                if(err) return response.send(err)
                response.send(result.rows);
            })
        }
    }) 
})

请帮助我指出我做错了什么。 预先感谢!

2 个答案:

答案 0 :(得分:0)

您可以删除json_agg()函数,并将SELECT列表中的所有列添加到子查询的GROUP BY列表中

SELECT row_to_json(row) as remixes
  FROM
  (
    SELECT 
          t."id", t."name", t."dateModified",
          json_build_object('some', tr."some") AS channels,
          t."userId", null AS "remixes"
      FROM "Tracks" t
      LEFT JOIN "Remixes" r ON r."originalTrackId" = t."id"
      LEFT JOIN "Tracks" tr ON tr."id" = r."remixTrackId"
     WHERE t."id" = '${trackId}'
  GROUP BY t."id", t."name", t."userId", tr."some", t."dateModified"
) row  

答案 1 :(得分:0)

我解决了,解决方案如下(在JS的帮助下):

const R = require('ramda')
const pg = require('pg')

app.get('/api/postgres/get-track', function(request, response) {
    const trackId = R.path(['query','id'], request)
    pool.connect(function(err, client, done) {
        if(err) {
            response.send("Could not connect to DB: " + err)
        } else {
            client.query(`
                SELECT 
                    t.*,
                    json_agg(json_build_object('name', tr."name", 'id', r."remixTrackId")) 
                    FILTER (WHERE tr."id" IS NOT NULL)
                    AS remixes
                FROM "Tracks" t
                    LEFT JOIN "Remixes" r ON r."originalTrackId" = t."id"
                    LEFT JOIN "Tracks" tr ON tr."id" = r."remixTrackId"
                WHERE t."id" = '${trackId}'
                GROUP BY t."id";
            `, function(err, result) {
                done()
                if(err) return response.send(err)
                const foundTrack = R.head(result.rows)
                if(foundTrack) {
                    response.send(foundTrack)
                } else {
                    //Error response here
                }
            })
        }
    }) 
})