v5 api: Sort Movies Randomly, passing seed as query parameter

This commit is contained in:
Arthur Jamet 2025-01-11 13:05:25 +00:00 committed by Zoe Roux
parent 57ae120d4d
commit 0e230114a7
No known key found for this signature in database
5 changed files with 60 additions and 4 deletions

View File

@ -20,5 +20,6 @@
"@types/pg": "^8.11.10",
"bun-types": "^1.1.42"
},
"module": "src/index.js"
"module": "src/index.js",
"packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72"
}

View File

@ -157,7 +157,7 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
.get(
"",
async ({
query: { limit, after, sort, filter },
query: { limit, after, sort, filter, random },
headers: { "accept-language": languages },
request: { url },
}) => {
@ -177,7 +177,12 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
.innerJoin(transQ, eq(shows.pk, transQ.pk))
.where(and(filter, keysetPaginate({ table: shows, after, sort })))
.orderBy(
...sort.map((x) => (x.desc ? sql`${shows[x.key]} desc nulls last` : shows[x.key])),
...(random !== undefined
? [sql`md5(${random} || ${shows.pk} )`]
: []),
...sort.map((x) =>
x.desc ? sql`${shows[x.key]} desc nulls last` : shows[x.key],
),
shows.pk,
)
.limit(limit);
@ -193,6 +198,12 @@ export const movies = new Elysia({ prefix: "/movies", tags: ["movies"] })
default: ["slug"],
description: "How to sort the query",
}),
random: t.Optional(
t.Integer({
minimum: 0,
description: "Seed to shuffle items",
}),
),
filter: t.Optional(Filter({ def: movieFilters })),
limit: t.Integer({
minimum: 1,

View File

@ -1,4 +1,4 @@
import { t } from "elysia";
import { t, TSchema } from "elysia";
export type Sort<
T extends string[],

View File

@ -7,6 +7,7 @@ import { bubble } from "~/models/examples";
import { dune1984 } from "~/models/examples/dune-1984";
import { dune } from "~/models/examples/dune-2021";
import { getMovies, movieApp } from "./movies-helper";
import { Movie } from "~/models/movie";
beforeAll(async () => {
await db.delete(shows);
@ -120,4 +121,46 @@ describe("Get all movies", () => {
next: null,
});
});
describe("Random sort", () => {
it("No limit, compare order with same seeds", async () => {
// First query
let [resp1, body1] = await getMovies({
random: 100,
});
expectStatus(resp1, body1).toBe(200);
const items1: Movie[] = body1.items;
const items1Ids = items1.map(({ id }) => id);
// Second query
let [resp2, body2] = await getMovies({
random: 100,
});
expectStatus(resp2, body2).toBe(200);
const items2: Movie[] = body2.items;
const items2Ids = items2.map(({ id }) => id);
expect(items1Ids).toEqual(items2Ids);
});
it("No limit, compare order with different seeds", async () => {
// First query
let [resp1, body1] = await getMovies({
random: 100,
});
expectStatus(resp1, body1).toBe(200);
const items1: Movie[] = body1.items;
const items1Ids = items1.map(({ id }) => id);
// Second query
let [resp2, body2] = await getMovies({
random: 1,
});
expectStatus(resp2, body2).toBe(200);
const items2: Movie[] = body2.items;
const items2Ids = items2.map(({ id }) => id);
console.log(items1Ids, items2Ids);
expect(items1Ids).not.toEqual(items2Ids);
});
});
});

View File

@ -30,6 +30,7 @@ export const getMovies = async ({
limit?: number;
after?: string;
sort?: string | string[];
random?: number;
langs?: string;
}) => {
const resp = await movieApp.handle(