From 4fb86089082eb030bf06cd2fe71fa0b47f14ca11 Mon Sep 17 00:00:00 2001 From: Eric Mc Sween <5454374+emcsween@users.noreply.github.com> Date: Thu, 25 Jun 2026 08:38:38 -0400 Subject: [PATCH] Merge pull request #34884 from overleaf/em-already-in-your-library Library import: flag entries that are already in the user's library GitOrigin-RevId: f3c92fb59283631e1a9e78d2e08a3a365981df45 --- .../web/frontend/extracted-translations.json | 1 + services/web/locales/en.json | 1 + .../backfill_library_references_search.mjs | 12 ++++--- ...create_libraryReferences_match_indexes.mjs | 36 +++++++++++++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 tools/migrations/20260619120000_create_libraryReferences_match_indexes.mjs diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 829d95a464..ff68d1c103 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -146,6 +146,7 @@ "all_these_experiments_are_available_exclusively": "", "allocate_license": "", "allows_to_search_by_author_title_etc_possible_to_pull_results_directly_from_your_reference_manager_if_connected": "", + "already_in_your_library": "", "an_email_has_already_been_sent_to": "", "an_error_occured_while_restoring_project": "", "and_much_more": "", diff --git a/services/web/locales/en.json b/services/web/locales/en.json index 342cf0a745..8e4adaca57 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -183,6 +183,7 @@ "allows_to_search_by_author_title_etc_possible_to_pull_results_directly_from_your_reference_manager_if_connected": "Allows to search by author, title, etc. Possible to pull results directly from your reference manager (if connected).", "already_have_an_account": "Already have an account?", "already_have_sl_account": "Already have an __appName__ account?", + "already_in_your_library": "Already in your library", "also": "Also", "alternatively_create_new_institution_account": "Alternatively, you can create a new account with your institution email (__email__) by clicking __clickText__.", "an_email_has_already_been_sent_to": "An email has already been sent to <0>__email__. Please wait and try again later.", diff --git a/services/web/scripts/backfill_library_references_search.mjs b/services/web/scripts/backfill_library_references_search.mjs index b381dae27e..92472dec32 100644 --- a/services/web/scripts/backfill_library_references_search.mjs +++ b/services/web/scripts/backfill_library_references_search.mjs @@ -4,6 +4,7 @@ import logger from '@overleaf/logger' import { db } from '../app/src/infrastructure/mongodb.mjs' import { buildSearchTokens, + buildMatchTokens, docSchema, } from '../modules/library/app/src/LibraryReferenceRepository.mts' import { tokenize } from '../modules/library/app/src/bibtex-search-tokens.mts' @@ -21,10 +22,10 @@ function usage() { {}, `Usage: node backfill_library_references_search.mjs [options] -Populates searchKey and searchTokens on libraryReferences so the -account-level library search can index them. Also unsets the obsolete -fields.$[].searchValue. Safe to rerun; picks up only un-indexed rows -by default. +Populates searchKey, searchTokens and matchTokens on libraryReferences so +the account-level library search and import duplicate-detection can index +them. Also unsets the obsolete fields.$[].searchValue. Safe to rerun; picks +up only un-indexed rows by default. Options: --commit Apply changes. Without this, runs as a dry run. @@ -73,11 +74,12 @@ async function backfill(trackProgress) { }) const searchKey = tokenize(doc.key) const searchTokens = buildSearchTokens(entry) + const matchTokens = buildMatchTokens(entry) ops.push({ updateOne: { filter: { _id: doc._id }, update: { - $set: { searchKey, searchTokens }, + $set: { searchKey, searchTokens, matchTokens }, $unset: { 'fields.$[].searchValue': 1 }, }, }, diff --git a/tools/migrations/20260619120000_create_libraryReferences_match_indexes.mjs b/tools/migrations/20260619120000_create_libraryReferences_match_indexes.mjs new file mode 100644 index 0000000000..d39a0a22d7 --- /dev/null +++ b/tools/migrations/20260619120000_create_libraryReferences_match_indexes.mjs @@ -0,0 +1,36 @@ +import Helpers from './lib/helpers.mjs' + +const tags = ['saas'] + +// Partial indexes so docs without a given match token are not indexed. They +// back the batch duplicate-detection query in findMatchingReferences. +const newIndexes = [ + { + key: { userId: 1, 'matchTokens.doi': 1 }, + name: 'userId_1_matchTokens.doi_1', + partialFilterExpression: { 'matchTokens.doi': { $exists: true } }, + }, + { + key: { userId: 1, 'matchTokens.authorTitleYear': 1 }, + name: 'userId_1_matchTokens.authorTitleYear_1', + partialFilterExpression: { + 'matchTokens.authorTitleYear': { $exists: true }, + }, + }, +] + +const migrate = async client => { + const { db } = client + await Helpers.addIndexesToCollection(db.libraryReferences, newIndexes) +} + +const rollback = async client => { + const { db } = client + await Helpers.dropIndexesFromCollection(db.libraryReferences, newIndexes) +} + +export default { + tags, + migrate, + rollback, +}