Skip to content

Commit

Permalink
chore(search): Send entity models for indexing
Browse files Browse the repository at this point in the history
With the change from the previous commit (accepting an ORM model rather than JSON for search indexing), we need to rewrite accordingly the parts of the code that use the search indexing.

Taking this opportunity to rewrite some code from promises to async/await syntax.
  • Loading branch information
MonkeyDo committed Feb 9, 2024
1 parent d451b0a commit 4767a89
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 116 deletions.
3 changes: 0 additions & 3 deletions src/common/helpers/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,6 @@ export async function generateIndex(orm) {
type: 'ngram'
}
}
}
},
'index.mapping.ignore_malformed': true
}
Expand Down Expand Up @@ -473,8 +472,6 @@ export async function generateIndex(orm) {

const areas = areaCollection.toJSON({omitPivot: true});

/** To index names, we use aliasSet.aliases.name and bbid, which Areas don't have.
* We massage the area to return a similar format as BB entities
/** To index names, we use aliases.name and bbid, which Areas don't have.
* We massage the area to return a similar format as BB entities
*/
Expand Down
20 changes: 3 additions & 17 deletions src/server/helpers/collectionRouteUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

import * as handler from '../helpers/handler';
import * as search from '../../common/helpers/search';
import {camelCase, differenceWith, isEqual, toLower, upperFirst} from 'lodash';
import {BadRequestError} from '../../common/helpers/error';

import log from 'log';

/**
* A handler for create or edit actions on collections.
Expand Down Expand Up @@ -89,22 +88,9 @@ export async function collectionCreateOrEditHandler(req, res, next) {
// if it's new or the name is changed,
// we need to update this collection in ElasticSearch index
if (isNew || res.locals.collection.name !== newCollection.get('name')) {
const collectionPromiseForES = new Promise((resolve) => {
const collectionForES = {
aliasSet: {
aliases: [
{name: newCollection.get('name')}
]
},
bbid: newCollection.get('id'),
id: newCollection.get('id'),
type: 'Collection'
};
resolve(collectionForES);
});
return handler.sendPromiseResult(res, collectionPromiseForES, search.indexEntity);
await search.indexEntity(newCollection);
}
return res.send(newCollection.toJSON());
return res.status(200).send(newCollection.toJSON());
}
catch (err) {
return next(err);
Expand Down
33 changes: 14 additions & 19 deletions src/server/routes/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import * as auth from '../helpers/auth';
import * as commonUtils from '../../common/helpers/utils';
import * as error from '../../common/helpers/error';
import * as handler from '../helpers/handler';
import * as propHelpers from '../../client/helpers/props';
import * as search from '../../common/helpers/search';
import {AdminActionType, PrivilegeType} from '../../common/helpers/privileges-utils';
Expand All @@ -42,6 +41,7 @@ import _ from 'lodash';
import express from 'express';
import {getOrderedCollectionsForEditorPage} from '../helpers/collections';
import {getOrderedRevisionForEditorPage} from '../helpers/revisions';
import log from 'log';
import target from '../templates/target';


Expand Down Expand Up @@ -122,8 +122,8 @@ function isCurrentUser(reqUserID, sessionUser) {
return reqUserID === sessionUser.id;
}

router.post('/edit/handler', auth.isAuthenticatedForHandler, (req, res) => {
async function runAsync() {
router.post('/edit/handler', auth.isAuthenticatedForHandler, async (req, res) => {
try {
const {Editor} = req.app.locals.orm;

if (!isCurrentUser(req.body.id, req.user)) {
Expand All @@ -140,10 +140,10 @@ router.post('/edit/handler', auth.isAuthenticatedForHandler, (req, res) => {
throw new error.NotFoundError('Editor not found', req);
});
if (editor.get('areaId') === req.body.areaId &&
editor.get('bio') === req.body.bio &&
editor.get('name') === req.body.name &&
editor.get('titleUnlockId') === req.body.title &&
editor.get('genderId') === req.body.genderId
editor.get('bio') === req.body.bio &&
editor.get('name') === req.body.name &&
editor.get('titleUnlockId') === req.body.title &&
editor.get('genderId') === req.body.genderId
) {
throw new error.FormSubmissionError('No change to the profile');
}
Expand All @@ -164,19 +164,14 @@ router.post('/edit/handler', auth.isAuthenticatedForHandler, (req, res) => {
});

res.locals.user.name = req.body.name;
const editorJSON = modifiedEditor.toJSON();
return {
aliasSet: {
aliases: [
{name: editorJSON.name}
]
},
bbid: editorJSON.id,
type: 'Editor'
};
}

handler.sendPromiseResult(res, runAsync(), search.indexEntity);
await search.indexEntity(modifiedEditor);

return res.status(200).send(modifiedEditor.toJSON());
}
catch (err) {
return error.sendErrorAsJSON(res, err);
}
});

router.post('/privs/edit/handler', auth.isAuthenticatedForHandler, auth.isAuthorized(ADMIN), async (req, res, next) => {
Expand Down
33 changes: 14 additions & 19 deletions src/server/routes/entity/entity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1165,33 +1165,28 @@ export async function processSingleEntity(formBody, JSONEntity, reqSession,
await indexAutoCreatedEditionGroup(orm, savedMainEntity, transacting);
}

const entityJSON = savedMainEntity.toJSON({omitPivot: true});
if (entityJSON && entityJSON.relationshipSet) {
entityJSON.relationshipSet.relationships = await Promise.all(entityJSON.relationshipSet.relationships.map(async (rel) => {
const entityRelationships = savedMainEntity.related('relationshipSet')?.related('relationships');
if (savedMainEntity.get('type') === 'Work' && entityRelationships?.length) {
const authorsOfWork = await Promise.all(entityRelationships.toJSON().filter(
// "Author wrote Work" relationship
(relation) => relation.typeId === 8
).map(async (relationshipJSON) => {
try {
rel.source = await commonUtils.getEntity(orm, rel.source.bbid, rel.source.type, {require: false, transacting});
rel.target = await commonUtils.getEntity(orm, rel.target.bbid, rel.target.type, {require: false, transacting});
const {source} = relationshipJSON;
const sourceEntity = await commonUtils.getEntity(
orm, source.bbid, source.type, {require: false, transacting}
);
return sourceEntity.name;
}
catch (err) {
log.error(err);
}
return rel;
return null;
}));
// Attach a work's authors for search indexing
if (savedMainEntity.get('type') === 'Work') {
const authorsOfWork = entityJSON.relationshipSet.relationships
.filter(
// "Author wrote Work" relationship
(relation) => relation.typeId === 8
)
.map((relation) => {
const {source} = relation;
return source.name;
});
entityJSON.authors = authorsOfWork;
}
savedMainEntity.set('authors', authorsOfWork.filter(Boolean));
}
return entityJSON;
return savedMainEntity;
}
catch (err) {
log.error(err);
Expand Down
4 changes: 2 additions & 2 deletions src/server/routes/entity/process-unified-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import * as achievement from '../../helpers/achievement';
import type {Request as $Request, Response as $Response} from 'express';
import {FormSubmissionError, sendErrorAsJSON} from '../../../common/helpers/error';
import {_bulkIndexEntities, getDocumentToIndex} from '../../../common/helpers/search';
import {authorToFormState, transformNewForm as authorTransform} from './author';
import {editionGroupToFormState, transformNewForm as editionGroupTransform} from './edition-group';
import {editionToFormState, transformNewForm as editionTransform} from './edition';
Expand All @@ -13,7 +14,6 @@ import type {
EntityTypeString
} from 'bookbrainz-data/lib/types/entity';
import _ from 'lodash';
import {_bulkIndexEntities} from '../../../common/helpers/search';
import log from 'log';
import {processSingleEntity} from './entity';

Expand Down Expand Up @@ -206,7 +206,7 @@ export async function handleCreateMultipleEntities(
}
// log indexing error if any
try {
_bulkIndexEntities(processedAchievements);
_bulkIndexEntities(processedEntities.map(en => getDocumentToIndex(en, en.get('type'))));
}
catch (err) {
log.error(err);
Expand Down
100 changes: 44 additions & 56 deletions src/server/routes/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,65 +93,53 @@ router.get('/details', middleware.loadGenders, (req, res) => {
}));
});

router.post('/handler', (req, res) => {
const {Editor, EditorType} = req.app.locals.orm;
router.post('/handler', async (req, res) => {
try {
const {Editor, EditorType} = req.app.locals.orm;

// Check whether the user is logged in - if so, redirect to profile page
if (req.user) {
return res.redirect(`/editor/${req.user.id}`);
}

if (!req.session.mbProfile) {
return res.redirect('/auth');
}

// Fetch the default EditorType from the database
const editorType = await EditorType.forge({label: 'Editor'})
.fetch({require: true});

// Create a new Editor and add to the database

const editor = await new Editor({
cachedMetabrainzName: req.session.mbProfile.sub,
genderId: req.body.gender,
metabrainzUserId: req.session.mbProfile.metabrainz_user_id,
name: req.body.displayName,
typeId: editorType.id
})
.save();

// Check whether the user is logged in - if so, redirect to profile page
if (req.user) {
return res.redirect(`/editor/${req.user.id}`);
}
req.session.mbProfile = null;

if (!req.session.mbProfile) {
return res.redirect('/auth');
await search.indexEntity(editor);
return res.status(200).send(editor.toJSON());
}
catch (err) {
if (_.isMatch(err, {constraint: 'editor_name_key'})) {
return error.sendErrorAsJSON(res, new error.FormSubmissionError(
'That username already exists - please try using another,' +
' or contact us to have your existing BookBrainz account' +
' linked to a MusicBrainz account.'
));
}
log.error(err);

return error.sendErrorAsJSON(res, new error.FormSubmissionError(
'Something went wrong when registering, please try again!'
));
}

// Fetch the default EditorType from the database
const registerPromise = EditorType.forge({label: 'Editor'})
.fetch({require: true})
.then(
// Create a new Editor and add to the database
(editorType) =>
new Editor({
cachedMetabrainzName: req.session.mbProfile.sub,
genderId: req.body.gender,
metabrainzUserId: req.session.mbProfile.metabrainz_user_id,
name: req.body.displayName,
typeId: editorType.id
})
.save()
)
.then((editor) => {
req.session.mbProfile = null;
const editorJSON = editor.toJSON();

// in ES index, we're storing the editor as entity
const editorForES = {};
editorForES.bbid = editorJSON.id;
editorForES.aliasSet = {
aliases: [
{name: editorJSON.name}
]
};
editorForES.type = 'Editor';
return editorForES;
})
.catch((err) => {
log.debug(err);

if (_.isMatch(err, {constraint: 'editor_name_key'})) {
throw new error.FormSubmissionError(
'That username already exists - please try using another,' +
' or contact us to have your existing BookBrainz account' +
' linked to a MusicBrainz account.'
);
}

throw new error.FormSubmissionError(
'Something went wrong when registering, please try again!'
);
});

return handler.sendPromiseResult(res, registerPromise, search.indexEntity);
});

export default router;

0 comments on commit 4767a89

Please sign in to comment.