fetch collections from new table (#179)

* fetch collections from new table

* optimization fixes

* fixed fields
This commit is contained in:
Arwid Thornström
2025-10-09 12:59:32 +02:00
committed by GitHub
parent a6097b0750
commit 3259fa702c
+42 -21
View File
@@ -27,8 +27,12 @@ export class CollectionAPI extends BaseSQLDataSource {
SELECT
id,
name,
metadata
FROM editorial_pages
metadata,
(SELECT array_agg(DISTINCT ecp.product_id)
FROM editorial_collection_products ecp
WHERE ecp.editorial_page_id = ep.id
) AS product_ids
FROM editorial_pages ep
WHERE type = 'collection' AND deleted IS NULL
ORDER BY name
`;
@@ -47,8 +51,12 @@ export class CollectionAPI extends BaseSQLDataSource {
SELECT
id,
name,
metadata
FROM editorial_pages
metadata,
(SELECT array_agg(DISTINCT ecp.product_id)
FROM editorial_collection_products ecp
WHERE ecp.editorial_page_id = ep.id
) AS product_ids
FROM editorial_pages ep
WHERE id = ? AND type = 'collection' AND deleted IS NULL
`;
const collection = await this.knex.raw(query, [id]).then((data) => {
@@ -61,12 +69,9 @@ export class CollectionAPI extends BaseSQLDataSource {
}
createCollectionFromRow(row: any): Collection {
let productIds: number[] = [];
if (row.metadata && Array.isArray(row.metadata.collection_products)) {
productIds = row.metadata.collection_products.map((id: string | number) =>
Number(id),
);
}
const productIds: number[] = Array.isArray(row.product_ids)
? row.product_ids
: [];
return {
id: row.id,
name: row.name,
@@ -85,35 +90,51 @@ export class CollectionAPI extends BaseSQLDataSource {
private async batchGetProductCollections(
productIds: readonly number[],
): Promise<Collection[][]> {
const productIdsStr = productIds.map(String);
const productIdsInt = productIds.map(Number);
const query = `
WITH collection_products AS (
SELECT
e.id,
e.name,
e.metadata,
jsonb_array_elements_text(e.metadata->'collection_products') AS product_id
array_agg(DISTINCT ecp.product_id) AS product_ids
FROM editorial_pages e
JOIN editorial_collection_products ecp ON ecp.editorial_page_id = e.id
WHERE e.type = 'collection'
AND e.deleted IS NULL
AND e.metadata->'collection_products' IS NOT NULL
GROUP BY e.id, e.name, e.metadata
)
SELECT * FROM collection_products
WHERE product_id = ANY (?)
SELECT
id,
name,
metadata,
product_ids
FROM collection_products
WHERE product_ids && ?::integer[];
`;
const results = await this.knex.raw(query, [productIdsStr]);
const results = await this.knex.raw(query, [productIdsInt]);
// Group collections by product ID
const collectionsByProduct: { [key: string]: Collection[] } = {};
productIdsStr.forEach((id) => {
productIdsInt.forEach((id) => {
collectionsByProduct[id] = [];
});
results.rows.forEach((row) => {
const productId = row.product_id;
if (!collectionsByProduct[productId])
const collection = this.createCollectionFromRow(row);
// Add this collection to each product ID that it contains
const collectionProductIds = row.product_ids || [];
collectionProductIds.forEach((productId: number) => {
if (productIdsInt.includes(productId)) {
if (!collectionsByProduct[productId]) {
collectionsByProduct[productId] = [];
collectionsByProduct[productId].push(this.createCollectionFromRow(row));
}
collectionsByProduct[productId].push(collection);
}
});
});
// Return collections in the same order as the input productIds
return productIdsStr.map((id) => collectionsByProduct[id] || []);
return productIdsInt.map((id) => collectionsByProduct[id] || []);
}
}