K
Kysely17mo ago
Blåhaj

Using `.orderBy` in JSON

Hey, I have a schema that roughly looks like this
export interface Member {
id: string;

activity: {
messages: number;
};
}
export interface Member {
id: string;

activity: {
messages: number;
};
}
and I want to query the db like that it gives me the top 10 Members with the highest activity.messages count. I figured out how I can orderBy but not inside of a json.
Solution:
try something like: ```ts const rows = await kysely .selectFrom("member")...
Jump to solution
25 Replies
Igal
Igal17mo ago
Hey 👋 Are you using Kysely 0.26.x? what dialect are you using?
Blåhaj
BlåhajOP17mo ago
pg (postgres) and I use newest Kysely
Igal
Igal17mo ago
In 0.26.x we've introduced type-safe JSON traversal, it's not documented yet in kysely.dev site, only in API docs and in the IDE. Lemme know if this works for you: https://kyse.link/?p=s&i=hKiV5qAL1BLLi3tvlwEq
const rows = await kysely
.selectFrom("member")
.selectAll()
.orderBy((eb) => eb.ref("activity", "->").key("messages"), "desc")
.limit(10)
.execute()
const rows = await kysely
.selectFrom("member")
.selectAll()
.orderBy((eb) => eb.ref("activity", "->").key("messages"), "desc")
.limit(10)
.execute()
SELECT
*
FROM
"member"
ORDER BY
"activity" -> 'messages' DESC
LIMIT
$1
SELECT
*
FROM
"member"
ORDER BY
"activity" -> 'messages' DESC
LIMIT
$1
Blåhaj
BlåhajOP17mo ago
will try when I’m home, than you :)
Blåhaj
BlåhajOP17mo ago
think
Blåhaj
BlåhajOP17mo ago
Blåhaj
BlåhajOP17mo ago
nvm was just vs code having it's moment
Igal
Igal17mo ago
did it work?
Blåhaj
BlåhajOP17mo ago
process crashes with
node:internal/streams/writable:303
throw new ERR_UNKNOWN_ENCODING(encoding);
^

TypeError [ERR_UNKNOWN_ENCODING]: Unknown encoding: uncaughtException
at new NodeError (node:internal/errors:399:5)
at _write (node:internal/streams/writable:303:13)
at Writable.write (node:internal/streams/writable:344:10)
at process.emit (node:events:511:28)
at process._fatalException (node:internal/process/execution:159:25) {
code: 'ERR_UNKNOWN_ENCODING'
}

Node.js v20.1.0
node:internal/streams/writable:303
throw new ERR_UNKNOWN_ENCODING(encoding);
^

TypeError [ERR_UNKNOWN_ENCODING]: Unknown encoding: uncaughtException
at new NodeError (node:internal/errors:399:5)
at _write (node:internal/streams/writable:303:13)
at Writable.write (node:internal/streams/writable:344:10)
at process.emit (node:events:511:28)
at process._fatalException (node:internal/process/execution:159:25) {
code: 'ERR_UNKNOWN_ENCODING'
}

Node.js v20.1.0
Blåhaj
BlåhajOP17mo ago
If I comment the .orderBy away it works
Igal
Igal17mo ago
what postgres version?
Blåhaj
BlåhajOP17mo ago
pg (npm package) or postgres on the server?
Igal
Igal17mo ago
server
Blåhaj
BlåhajOP17mo ago
PostgreSQL 14.8 (Ubuntu 14.8-0ubuntu0.22.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0, 64-bit
Igal
Igal17mo ago
I've added some test cases for json traversal in order by clauses https://github.com/kysely-org/kysely/pull/621 and everything seems to be OK. we use pg 8.11.0 and postgres 15.x images.
Blåhaj
BlåhajOP17mo ago
@Igal I found the issue, in your example you used the -> operator but it's ->>, it works now
Igal
Igal17mo ago
it should work with -> too. how's the column defined? json or jsonb?
Blåhaj
BlåhajOP17mo ago
.addColumn("activity", "json", (col)
Igal
Igal17mo ago
bingo, when changing the data type to json in tests it errors for order by with: error: could not identify an ordering operator for type json and works again when changing to ->>.
Blåhaj
BlåhajOP17mo ago
I already paniced because I didn't know what I should do and just randomly was scrolling through the test file and found the ->>, tried it and worked lol thanks anyway
Blåhaj
BlåhajOP17mo ago
https://c.lunish.nl/r/4hU8WT.mp4 I am kind of lost here, why are the activity.messages higher on page 1 than on page 0? (each page only adds an offset [page] * 10)
koskimas
koskimas17mo ago
->> casts the thing you access to a string. The sorting is done using a stringified number. You probably need to explicitly cast to integer
Blåhaj
BlåhajOP17mo ago
ah okey, how do I do that (lol) (@Igal^)
Solution
Igal
Igal17mo ago
try something like:
const rows = await kysely
.selectFrom("member")
.selectAll()
.orderBy((eb) => sql`cast(${eb.ref("activity", "->>").key("messages")} as integer)`, "desc")
.limit(10)
.execute()
const rows = await kysely
.selectFrom("member")
.selectAll()
.orderBy((eb) => sql`cast(${eb.ref("activity", "->>").key("messages")} as integer)`, "desc")
.limit(10)
.execute()
Blåhaj
BlåhajOP17mo ago
yey that seems to work!! thank you
Want results from more Discord servers?
Add your server