From e05158b376dfbd25a286ee3f911359749de0106a Mon Sep 17 00:00:00 2001 From: Zach Smith Date: Mon, 9 Jan 2023 07:47:09 +0200 Subject: [PATCH] Updated indexing system toname indices correctly when create (#70) and updated lists collection to have a f text index for searching multiple fields by text values (#18) --- .../mutations/save-list/_save-curated-list.js | 6 ++- api/src/mongo/collections/_lists.js | 23 +++++++++ api/src/mongo/collections/_permissions.js | 17 +++---- api/src/mongo/collections/_roles.js | 17 +++---- api/src/mongo/collections/_users.js | 1 + api/src/mongo/index.js | 47 ++++++++++++------- clients/src/pages/index/routes.js | 2 +- 7 files changed, 78 insertions(+), 35 deletions(-) diff --git a/api/src/graphql/resolvers/mutations/save-list/_save-curated-list.js b/api/src/graphql/resolvers/mutations/save-list/_save-curated-list.js index 7ae518019..f8339504a 100644 --- a/api/src/graphql/resolvers/mutations/save-list/_save-curated-list.js +++ b/api/src/graphql/resolvers/mutations/save-list/_save-curated-list.js @@ -1,10 +1,11 @@ import { ObjectId } from 'mongodb' import userModel from '../../../../user-model/index.js' import PERMISSIONS from '../../../../user-model/permissions.js' +import { PASSPORT_SSO_SESSION_ID } from '../../../../config/index.js' export default async (self, args, ctx) => { await userModel.ensurePermission({ ctx, permission: PERMISSIONS['list:update'] }) - const { id, filter = {}, createdBy, ...otherFields } = args + const { id, filter = {}, createdBy, type, ...otherFields } = args const { Lists } = await ctx.mongo.collections const _id = ObjectId() @@ -17,6 +18,9 @@ export default async (self, args, ctx) => { $setOnInsert: { _id, createdAt: new Date(), + type, + userId: ctx.user.info(ctx)?.id || undefined, + clientSession: ctx.cookies.get(PASSPORT_SSO_SESSION_ID) || 'no-session', // This can happen if the user blocks cookies }, $set: { modifiedAt: new Date(), diff --git a/api/src/mongo/collections/_lists.js b/api/src/mongo/collections/_lists.js index 7de3f5c97..f7cfb1786 100644 --- a/api/src/mongo/collections/_lists.js +++ b/api/src/mongo/collections/_lists.js @@ -21,6 +21,18 @@ export default { bsonType: 'string', description: 'List description', }, + createdBy: { + bsonType: 'string', + description: 'The person or application that created the list', + }, + userId: { + description: + 'ID of logged in user who requested the list be created (if user is logged in)', + }, + clientSession: { + bsonType: 'string', + description: 'ID of the browser session if it exists', + }, }, }, }, @@ -28,9 +40,20 @@ export default { { index: 'hashOfFilter', options: { + name: 'hashOfFilter', unique: true, partialFilterExpression: { hashOfFilter: { $exists: true } }, }, }, + { + _type: 'text', + createdBy: 'text', + description: 'text', + title: 'text', + type: 'text', + options: { + name: 'text', + }, + }, ], } diff --git a/api/src/mongo/collections/_permissions.js b/api/src/mongo/collections/_permissions.js index 397a9a4b1..93cc6fa86 100644 --- a/api/src/mongo/collections/_permissions.js +++ b/api/src/mongo/collections/_permissions.js @@ -1,13 +1,5 @@ export default { name: 'permissions', - indices: [ - { - index: 'name', - options: { - unique: true, - }, - }, - ], validator: { $jsonSchema: { bsonType: 'object', @@ -21,4 +13,13 @@ export default { }, }, }, + indices: [ + { + index: 'name', + options: { + name: 'name', + unique: true, + }, + }, + ], } diff --git a/api/src/mongo/collections/_roles.js b/api/src/mongo/collections/_roles.js index d205db864..4536ead29 100644 --- a/api/src/mongo/collections/_roles.js +++ b/api/src/mongo/collections/_roles.js @@ -1,13 +1,5 @@ export default { name: 'roles', - indices: [ - { - index: 'name', - options: { - unique: true, - }, - }, - ], validator: { $jsonSchema: { bsonType: 'object', @@ -21,4 +13,13 @@ export default { }, }, }, + indices: [ + { + index: 'name', + options: { + name: 'name', + unique: true, + }, + }, + ], } diff --git a/api/src/mongo/collections/_users.js b/api/src/mongo/collections/_users.js index 7db13110f..db0095563 100644 --- a/api/src/mongo/collections/_users.js +++ b/api/src/mongo/collections/_users.js @@ -17,6 +17,7 @@ export default { { index: 'emailAddress', options: { + name: 'emailAddress', unique: true, }, }, diff --git a/api/src/mongo/index.js b/api/src/mongo/index.js index c1971bf24..756e546fe 100644 --- a/api/src/mongo/index.js +++ b/api/src/mongo/index.js @@ -111,24 +111,37 @@ export const updateValidationRules = async () => { Object.entries(_collections) .map(([, { name, indices = [] }]) => { return Promise.all( - indices.map(async ({ index, options }) => { - console.info('Applying index', index, 'to collection', name, options) - return _db - .collection(name) - .createIndex(index, options) - .catch(async error => { - if (error.code === 85) { - console.info('Recreating index on', name, ':: Index name:', index) - try { - await _db.collection(name).dropIndex(`${index}_1`) - await _db.collection(name).createIndex(index, options) - } catch (error) { - throw new Error(`Unable to recreate index. ${error.message}`) - } - } else { - throw error + indices.map(async ({ _type = undefined, options, ...indexFields }) => { + const collection = await _db.collection(name) + try { + if (_type === 'text') { + console.info( + 'Applying text index', + options.name, + 'to collection', + name, + indexFields, + options + ) + return collection.createIndex(indexFields, options) + } else { + const { index } = indexFields + console.info('Applying index', index, 'to collection', name, options) + return collection.createIndex(index, options) + } + } catch (error) { + if (error.code === 85) { + console.info('Recreating index on', name, ':: Index', indexFields) + try { + await _db.collection(name).dropIndex(options.name) + await _db.collection(name).createIndex(index, options) + } catch (error) { + throw new Error(`Unable to recreate index. ${error.message}`) } - }) + } else { + throw error + } + } }) ) }) diff --git a/clients/src/pages/index/routes.js b/clients/src/pages/index/routes.js index 8ea5f6332..d92bc9da8 100644 --- a/clients/src/pages/index/routes.js +++ b/clients/src/pages/index/routes.js @@ -84,7 +84,7 @@ export default [ ), }, { - label: 'Data lists', + label: 'Curated lists', to: '/data-lists', includeInFooter: true, Icon: CollectionsIcon,