From efce1c839ef971cf016fd21408d35f2ea9cbb349 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Fri, 9 Oct 2020 20:06:54 +0100 Subject: [PATCH 1/2] Major performance boost to attachLinks -> makes CSV upload much more snappy. --- packages/server/src/db/linkedRecords/index.js | 23 ++++++++++--------- .../server/src/db/linkedRecords/linkUtils.js | 2 ++ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/server/src/db/linkedRecords/index.js b/packages/server/src/db/linkedRecords/index.js index 115553696c..842900f815 100644 --- a/packages/server/src/db/linkedRecords/index.js +++ b/packages/server/src/db/linkedRecords/index.js @@ -88,23 +88,24 @@ exports.attachLinkInfo = async (instanceId, records) => { records = [records] wasArray = false } + let modelIds = [...new Set(records.map(el => el.modelId))] // start by getting all the link values for performance reasons - let responses = await Promise.all( - records.map(record => - getLinkDocuments({ - instanceId, - modelId: record.modelId, - recordId: record._id, - includeDocs: IncludeDocs.EXCLUDE, - }) + let responses = [].concat.apply( + [], + await Promise.all( + modelIds.map(modelId => + getLinkDocuments({ + instanceId, + modelId: modelId, + includeDocs: IncludeDocs.EXCLUDE, + }) + ) ) ) - // can just use an index to access responses, order maintained - let index = 0 // now iterate through the records and all field information for (let record of records) { // get all links for record, ignore fieldName for now - const linkVals = responses[index++] + const linkVals = responses.filter(el => el.thisId === record._id) for (let linkVal of linkVals) { // work out which link pertains to this record if (!(record[linkVal.fieldName] instanceof Array)) { diff --git a/packages/server/src/db/linkedRecords/linkUtils.js b/packages/server/src/db/linkedRecords/linkUtils.js index 7680a2603f..f5fe1f6786 100644 --- a/packages/server/src/db/linkedRecords/linkUtils.js +++ b/packages/server/src/db/linkedRecords/linkUtils.js @@ -27,10 +27,12 @@ exports.createLinkView = async instanceId => { let doc2 = doc.doc2 emit([doc1.modelId, doc1.recordId], { id: doc2.recordId, + thisId: doc1.recordId, fieldName: doc1.fieldName, }) emit([doc2.modelId, doc2.recordId], { id: doc1.recordId, + thisId: doc2.recordId, fieldName: doc2.fieldName, }) } From 03584cacb22ded7ed0c4c0d957937a22350fe95a Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 12 Oct 2020 10:28:53 +0100 Subject: [PATCH 2/2] Using lodash flatten rather than pure JS. --- packages/server/src/db/linkedRecords/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/db/linkedRecords/index.js b/packages/server/src/db/linkedRecords/index.js index 842900f815..ba93f3d2e8 100644 --- a/packages/server/src/db/linkedRecords/index.js +++ b/packages/server/src/db/linkedRecords/index.js @@ -1,5 +1,6 @@ const LinkController = require("./LinkController") const { IncludeDocs, getLinkDocuments, createLinkView } = require("./linkUtils") +const _ = require("lodash") /** * This functionality makes sure that when records with links are created, updated or deleted they are processed @@ -90,8 +91,7 @@ exports.attachLinkInfo = async (instanceId, records) => { } let modelIds = [...new Set(records.map(el => el.modelId))] // start by getting all the link values for performance reasons - let responses = [].concat.apply( - [], + let responses = _.flatten( await Promise.all( modelIds.map(modelId => getLinkDocuments({