From 7763a8a939bcc2aa478c77d93bc81cbc5aea18d2 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Mon, 23 Oct 2023 10:52:03 +0800 Subject: [PATCH] perf: limit search item results to 100 a time and fetch labels and recommendations only needed --- packages/api/src/resolvers/article/index.ts | 22 ++------ .../api/src/resolvers/function_resolvers.ts | 52 ++++++++++++++++--- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/packages/api/src/resolvers/article/index.ts b/packages/api/src/resolvers/article/index.ts index bd016a345..54b9fcfba 100644 --- a/packages/api/src/resolvers/article/index.ts +++ b/packages/api/src/resolvers/article/index.ts @@ -57,6 +57,7 @@ import { findHighlightsByLibraryItemId } from '../../services/highlights' import { addLabelsToLibraryItem, findLabelsByIds, + findLabelsByLibraryItemId, findOrCreateLabels, saveLabelsInLibraryItem, } from '../../services/labels' @@ -69,6 +70,7 @@ import { updateLibraryItemReadingProgress, updateLibraryItems, } from '../../services/library_item' +import { findRecommendationsByLibraryItemId } from '../../services/recommendation' import { parsedContentToLibraryItem } from '../../services/save_page' import { findUploadFileById, @@ -610,7 +612,7 @@ export const searchResolver = authorized< QuerySearchArgs >(async (_obj, params, { log, uid }) => { const startCursor = params.after || '' - const first = params.first || 10 + const first = Math.min(params.first || 10, 100) // limit to 100 items // the query size is limited to 255 characters if (params.query && params.query.length > 255) { @@ -641,25 +643,7 @@ export const searchResolver = authorized< libraryItems.pop() } - await Promise.all( - libraryItems.map(async (libraryItem) => { - if ( - libraryItem.highlightAnnotations && - libraryItem.highlightAnnotations.length > 0 - ) { - // fetch highlights for each item - libraryItem.highlights = await findHighlightsByLibraryItemId( - libraryItem.id, - uid - ) - } - }) - ) - const edges = libraryItems.map((libraryItem) => { - if (libraryItem.siteIcon && !isBase64Image(libraryItem.siteIcon)) { - libraryItem.siteIcon = createImageProxyUrl(libraryItem.siteIcon, 128, 128) - } if (params.includeContent && libraryItem.readableContent) { // convert html to the requested format const format = params.format || ArticleFormat.Html diff --git a/packages/api/src/resolvers/function_resolvers.ts b/packages/api/src/resolvers/function_resolvers.ts index c2cc34f9a..bc58b54bf 100644 --- a/packages/api/src/resolvers/function_resolvers.ts +++ b/packages/api/src/resolvers/function_resolvers.ts @@ -6,15 +6,19 @@ import { Subscription } from '../entity/subscription' import { Article, + Highlight, Label, PageType, Recommendation, SearchItem, } from '../generated/graphql' +import { findHighlightsByLibraryItemId } from '../services/highlights' import { findLabelsByLibraryItemId } from '../services/labels' import { findRecommendationsByLibraryItemId } from '../services/recommendation' import { findUploadFileById } from '../services/upload_file' import { + highlightDataToHighlight, + isBase64Image, recommandationDataToRecommendation, validatedDate, wordsCount, @@ -483,30 +487,64 @@ export const functionResolvers = { if (item.wordCount) return item.wordCount return item.content ? wordsCount(item.content) : undefined }, + siteIcon(item: { siteIcon?: string }) { + if (item.siteIcon && !isBase64Image(item.siteIcon)) { + return createImageProxyUrl(item.siteIcon, 128, 128) + } + + return item.siteIcon + }, + async highlights( + item: { + id: string + highlights?: Highlight[] + highlightAnnotations?: string[] | null + }, + _: unknown, + ctx: WithDataSourcesContext + ) { + if (item.highlights) return item.highlights + + if (item.highlightAnnotations && item.highlightAnnotations.length > 0) { + const highlights = await findHighlightsByLibraryItemId(item.id, ctx.uid) + return highlights.map(highlightDataToHighlight) + } + + return [] + }, async labels( - item: { id: string; labels?: Label[] }, + item: { id: string; labels?: Label[]; labelNames?: string[] | null }, _: unknown, ctx: WithDataSourcesContext ) { if (item.labels) return item.labels - return findLabelsByLibraryItemId(item.id, ctx.uid) + if (item.labelNames && item.labelNames.length > 0) { + return findLabelsByLibraryItemId(item.id, ctx.uid) + } + + return [] }, async recommendations( item: { id: string recommendations?: Recommendation[] + recommenderNames?: string[] | null }, _: unknown, ctx: WithDataSourcesContext ) { if (item.recommendations) return item.recommendations - const recommendations = await findRecommendationsByLibraryItemId( - item.id, - ctx.uid - ) - return recommendations.map(recommandationDataToRecommendation) + if (item.recommenderNames && item.recommenderNames.length > 0) { + const recommendations = await findRecommendationsByLibraryItemId( + item.id, + ctx.uid + ) + return recommendations.map(recommandationDataToRecommendation) + } + + return [] }, }, Subscription: {