From d4404b02489144cf19113d6889d957dcadf47a73 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Wed, 4 Oct 2023 14:54:12 +0800 Subject: [PATCH] fetch labels and highlights after items fetched in a search query --- packages/api/src/resolvers/article/index.ts | 3 +- .../api/src/resolvers/function_resolvers.ts | 41 ++++++++++++++++--- packages/api/src/services/highlights.ts | 18 ++++++++ packages/api/src/services/labels.ts | 26 ++++++++++++ packages/api/src/services/library_item.ts | 6 +-- .../0128.do.create_index_for_foreign_key.sql | 4 +- ...0128.undo.create_index_for_foreign_key.sql | 9 ++-- 7 files changed, 90 insertions(+), 17 deletions(-) diff --git a/packages/api/src/resolvers/article/index.ts b/packages/api/src/resolvers/article/index.ts index 3a915006a..f2ae8f800 100644 --- a/packages/api/src/resolvers/article/index.ts +++ b/packages/api/src/resolvers/article/index.ts @@ -649,7 +649,6 @@ export const searchResolver = authorized< size: first + 1, // fetch one more item to get next cursor sort: searchQuery.sort, includePending: true, - includeContent: params.includeContent ?? false, ...searchQuery, }, uid @@ -738,7 +737,7 @@ export const updatesSinceResolver = authorized< from: Number(startCursor), size: size + 1, // fetch one more item to get next cursor includeDeleted: true, - dateFilters: [{ field: 'updated_at', startDate }], + dateFilters: [{ field: 'updatedAt', startDate }], sort, }, uid diff --git a/packages/api/src/resolvers/function_resolvers.ts b/packages/api/src/resolvers/function_resolvers.ts index ece9cfe66..57f702a59 100644 --- a/packages/api/src/resolvers/function_resolvers.ts +++ b/packages/api/src/resolvers/function_resolvers.ts @@ -4,9 +4,21 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { Subscription } from '../entity/subscription' -import { Article, PageType, SearchItem } from '../generated/graphql' +import { + Article, + Highlight, + Label, + PageType, + SearchItem, +} from '../generated/graphql' +import { findHighlightsByLibraryItemId } from '../services/highlights' +import { findLabelsByLibraryItemId } from '../services/labels' import { findUploadFileById } from '../services/upload_file' -import { validatedDate, wordsCount } from '../utils/helpers' +import { + highlightDataToHighlight, + validatedDate, + wordsCount, +} from '../utils/helpers' import { createImageProxyUrl } from '../utils/imageproxy' import { generateDownloadSignedUrl, @@ -467,9 +479,28 @@ export const functionResolvers = { originalArticleUrl(item: { url: string }) { return item.url }, - wordsCount(article: { wordCount?: number; content?: string }) { - if (article.wordCount) return article.wordCount - return article.content ? wordsCount(article.content) : undefined + wordsCount(item: { wordCount?: number; content?: string }) { + if (item.wordCount) return item.wordCount + return item.content ? wordsCount(item.content) : undefined + }, + async highlights( + item: { id: string; highlights?: Highlight[] }, + _: unknown, + ctx: WithDataSourcesContext + ) { + if (item.highlights) return item.highlights + + const highlights = await findHighlightsByLibraryItemId(item.id, ctx.uid) + return highlights.map(highlightDataToHighlight) + }, + async labels( + item: { id: string; labels?: Label[] }, + _: unknown, + ctx: WithDataSourcesContext + ) { + if (item.labels) return item.labels + + return findLabelsByLibraryItemId(item.id, ctx.uid) }, }, Subscription: { diff --git a/packages/api/src/services/highlights.ts b/packages/api/src/services/highlights.ts index 6c452df2f..07cf73eba 100644 --- a/packages/api/src/services/highlights.ts +++ b/packages/api/src/services/highlights.ts @@ -160,3 +160,21 @@ export const findHighlightById = async ( userId ) } + +export const findHighlightsByLibraryItemId = async ( + libraryItemId: string, + userId: string +) => { + return authTrx( + async (tx) => + tx.withRepository(highlightRepository).find({ + where: { libraryItem: { id: libraryItemId } }, + relations: { + user: true, + labels: true, + }, + }), + undefined, + userId + ) +} diff --git a/packages/api/src/services/labels.ts b/packages/api/src/services/labels.ts index bfb109db7..0b84cc829 100644 --- a/packages/api/src/services/labels.ts +++ b/packages/api/src/services/labels.ts @@ -2,6 +2,7 @@ import { FindOptionsWhere, In } from 'typeorm' import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity' import { EntityLabel } from '../entity/entity_label' import { Label } from '../entity/label' +import { LibraryItem } from '../entity/library_item' import { createPubSubClient, EntityType } from '../pubsub' import { authTrx } from '../repository' import { CreateLabelInput, labelRepository } from '../repository/label' @@ -236,3 +237,28 @@ export const findLabelById = async (id: string, userId: string) => { userId ) } + +export const findLabelsByLibraryItemId = async ( + libraryItemId: string, + userId: string +) => { + return authTrx( + async (tx) => + tx + .createQueryBuilder(Label, 'label') + .innerJoin( + EntityLabel, + 'entityLabel', + 'entityLabel.label_id = label.id' + ) + .innerJoin( + LibraryItem, + 'LibraryItem', + 'LibraryItem.id = entityLabel.library_item_id' + ) + .where('LibraryItem.id = :libraryItemId', { libraryItemId }) + .getMany(), + undefined, + userId + ) +} diff --git a/packages/api/src/services/library_item.ts b/packages/api/src/services/library_item.ts index ba2eba838..68868c8fd 100644 --- a/packages/api/src/services/library_item.ts +++ b/packages/api/src/services/library_item.ts @@ -6,7 +6,7 @@ import { Label } from '../entity/label' import { LibraryItem, LibraryItemState } from '../entity/library_item' import { BulkActionType } from '../generated/graphql' import { createPubSubClient, EntityType } from '../pubsub' -import { authTrx } from '../repository' +import { authTrx, getColumns } from '../repository' import { libraryItemRepository } from '../repository/library_item' import { wordsCount } from '../utils/helpers' import { @@ -275,10 +275,6 @@ export const searchLibraryItems = async ( async (tx) => { const queryBuilder = tx .createQueryBuilder(LibraryItem, 'library_item') - .leftJoinAndSelect('library_item.labels', 'labels') - .leftJoinAndSelect('library_item.highlights', 'highlights') - .leftJoinAndSelect('highlights.user', 'user') - .leftJoinAndSelect('user.profile', 'profile') .leftJoinAndSelect('library_item.recommendations', 'recommendations') .leftJoinAndSelect('recommendations.recommender', 'recommender') .leftJoinAndSelect('recommendations.group', 'group') diff --git a/packages/db/migrations/0128.do.create_index_for_foreign_key.sql b/packages/db/migrations/0128.do.create_index_for_foreign_key.sql index edbd4ae92..305d522bc 100755 --- a/packages/db/migrations/0128.do.create_index_for_foreign_key.sql +++ b/packages/db/migrations/0128.do.create_index_for_foreign_key.sql @@ -11,6 +11,8 @@ CREATE INDEX IF NOT EXISTS highlight_library_item_id_idx ON omnivore.highlight ( CREATE INDEX IF NOT EXISTS user_profile_user_id_idx ON omnivore.user_profile (user_id); -CREATE INDEX IF NOT EXISTS library_item_user_id_idx ON omnivore.library_item (user_id); +-- create index for sorting +CREATE INDEX IF NOT EXISTS library_item_saved_at_idx ON omnivore.library_item (saved_at); +CREATE INDEX IF NOT EXISTS library_item_updated_at_idx ON omnivore.library_item (updated_at); COMMIT; diff --git a/packages/db/migrations/0128.undo.create_index_for_foreign_key.sql b/packages/db/migrations/0128.undo.create_index_for_foreign_key.sql index e46cb3613..87612778e 100755 --- a/packages/db/migrations/0128.undo.create_index_for_foreign_key.sql +++ b/packages/db/migrations/0128.undo.create_index_for_foreign_key.sql @@ -4,13 +4,14 @@ BEGIN; +DROP INDEX IF EXISTS omnivore.library_item_updated_at_idx; +DROP INDEX IF EXISTS omnivore.library_item_saved_at_idx; + +DROP INDEX IF NOT EXISTS omnivore.user_profile_user_id_idx; + DROP INDEX IF EXISTS omnivore.highlight_library_item_id_idx; DROP INDEX IF EXISTS omnivore.entity_labels_highlight_id_idx; DROP INDEX IF EXISTS omnivore.entity_labels_library_item_id_idx; -DROP INDEX IF NOT EXISTS omnivore.user_profile_user_id_idx; - -DROP INDEX IF NOT EXISTS omnivore.library_item_user_id_idx; - COMMIT;