Updating to use a sub-query with a wrapper to get the JSON aggregations.

This commit is contained in:
mike12345567 2024-09-04 16:17:25 +01:00
parent eefb1f01a3
commit 79de7b2c45
1 changed files with 8 additions and 12 deletions

View File

@ -913,30 +913,26 @@ class InternalBuilder {
const fieldList: string = relationshipFields const fieldList: string = relationshipFields
.map(field => jsonField(field)) .map(field => jsonField(field))
.join(",") .join(",")
let rawJsonArray: Knex.Raw, limit: number let rawJsonArray: Knex.Raw
switch (sqlClient) { switch (sqlClient) {
case SqlClient.SQL_LITE: case SqlClient.SQL_LITE:
rawJsonArray = this.knex.raw( rawJsonArray = this.knex.raw(
`json_group_array(json_object(${fieldList}))` `json_group_array(json_object(${fieldList}))`
) )
limit = getBaseLimit()
break break
case SqlClient.POSTGRES: case SqlClient.POSTGRES:
rawJsonArray = this.knex.raw( rawJsonArray = this.knex.raw(
`json_agg(json_build_object(${fieldList}))` `json_agg(json_build_object(${fieldList}))`
) )
limit = 1
break break
case SqlClient.MY_SQL: case SqlClient.MY_SQL:
case SqlClient.ORACLE: case SqlClient.ORACLE:
rawJsonArray = this.knex.raw( rawJsonArray = this.knex.raw(
`json_arrayagg(json_object(${fieldList}))` `json_arrayagg(json_object(${fieldList}))`
) )
limit = getBaseLimit()
break break
case SqlClient.MS_SQL: case SqlClient.MS_SQL:
rawJsonArray = this.knex.raw(`json_array(json_object(${fieldList}))`) rawJsonArray = this.knex.raw(`json_array(json_object(${fieldList}))`)
limit = 1
break break
default: default:
throw new Error(`JSON relationships not implement for ${this.client}`) throw new Error(`JSON relationships not implement for ${this.client}`)
@ -945,16 +941,12 @@ class InternalBuilder {
// it reduces the result set rather than limiting how much data it filters over // it reduces the result set rather than limiting how much data it filters over
const primaryKey = `${toAlias}.${toPrimary || toKey}` const primaryKey = `${toAlias}.${toPrimary || toKey}`
let subQuery = this.knex let subQuery = this.knex
.select(rawJsonArray) .select(`${toAlias}.*`)
.from(toTableWithSchema) .from(toTableWithSchema)
.limit(limit) .limit(getBaseLimit())
// add sorting to get consistent order // add sorting to get consistent order
.orderBy(primaryKey) .orderBy(primaryKey)
if (sqlClient === SqlClient.POSTGRES) {
subQuery = subQuery.groupBy(primaryKey)
}
// many-to-many relationship with junction table // many-to-many relationship with junction table
if (throughTable && toPrimary && fromPrimary) { if (throughTable && toPrimary && fromPrimary) {
const throughAlias = aliases?.[throughTable] || throughTable const throughAlias = aliases?.[throughTable] || throughTable
@ -985,7 +977,11 @@ class InternalBuilder {
if (this.client === SqlClient.SQL_LITE) { if (this.client === SqlClient.SQL_LITE) {
subQuery = this.addJoinFieldCheck(subQuery, relationship) subQuery = this.addJoinFieldCheck(subQuery, relationship)
} }
query = query.select({ [relationship.column]: subQuery }) // @ts-ignore - the from alias syntax isn't in Knex typing
const wrapperQuery = this.knex.select(rawJsonArray).from({
[toAlias]: subQuery,
})
query = query.select({ [relationship.column]: wrapperQuery })
} }
return query return query
} }