From 4e6168d8fa3b0520e85748c61c041c1fbb8a0e09 Mon Sep 17 00:00:00 2001 From: Daniel Avila Date: Sat, 18 Mar 2023 18:40:53 -0400 Subject: [PATCH] setup message population on search --- api/lib/db/mongoMeili.js | 19 ++++++------ api/server/routes/search.js | 9 ++++++ client/src/components/Messages/Message.jsx | 4 +-- client/src/store/messageSlice.js | 4 ++- client/src/utils/buildTree.js | 34 +++++++++++++++------- 5 files changed, 47 insertions(+), 23 deletions(-) diff --git a/api/lib/db/mongoMeili.js b/api/lib/db/mongoMeili.js index c603568e1a..63330b4624 100644 --- a/api/lib/db/mongoMeili.js +++ b/api/lib/db/mongoMeili.js @@ -9,7 +9,8 @@ const validateOptions = function (options) { }; const createMeiliMongooseModel = function ({ index, indexName, client, attributesToIndex }) { - console.log('attributesToIndex', attributesToIndex); + // console.log('attributesToIndex', attributesToIndex); + const primaryKey = attributesToIndex[0]; // MeiliMongooseModel is of type Mongoose.Model class MeiliMongooseModel { // Clear Meili index @@ -24,7 +25,7 @@ const createMeiliMongooseModel = function ({ index, indexName, client, attribute static async resetIndex() { await this.clearMeiliIndex(); - await client.createIndex(indexName, { primaryKey: attributesToIndex[0] }); + await client.createIndex(indexName, { primaryKey }); } // Clear Meili index // Push a mongoDB collection to Meili index @@ -52,24 +53,24 @@ const createMeiliMongooseModel = function ({ index, indexName, client, attribute // Populate hits with content from mongodb if (populate) { // Find objects into mongodb matching `objectID` from Meili search + const query = {}; + query[primaryKey] = { $in: _.map(data.hits, primaryKey) }; const hitsFromMongoose = await this.find( - { - _id: { $in: _.map(data.hits, '_id') } - }, + query, _.reduce( this.schema.obj, function (results, value, key) { return { ...results, [key]: 1 }; }, { _id: 1 } - ) + ), ); // Add additional data from mongodb into Meili search hits const populatedHits = data.hits.map(function (hit) { - const originalHit = _.find(hitsFromMongoose, { - _id: hit._id - }); + const query = {}; + query[primaryKey] = hit[primaryKey]; + const originalHit = _.find(hitsFromMongoose, query); return { ...(originalHit ? originalHit.toJSON() : {}), diff --git a/api/server/routes/search.js b/api/server/routes/search.js index e563966a57..0b667580b5 100644 --- a/api/server/routes/search.js +++ b/api/server/routes/search.js @@ -46,4 +46,13 @@ router.get('/clear', async function (req, res) { res.send('cleared'); }); +router.get('/test', async function (req, res) { + const { q } = req.query; + const messages = (await Message.meiliSearch(q, { attributesToHighlight: ['text'] }, true)).hits.map(message => { + const { _formatted, ...rest } = message; + return { ...rest, searchResult: true, text: _formatted.text }; + }); + res.send(messages); +}); + module.exports = router; diff --git a/client/src/components/Messages/Message.jsx b/client/src/components/Messages/Message.jsx index e3a2b5c82e..c009b1c3b2 100644 --- a/client/src/components/Messages/Message.jsx +++ b/client/src/components/Messages/Message.jsx @@ -22,7 +22,7 @@ export default function Message({ (state) => state.submit ); const [abortScroll, setAbort] = useState(false); - const { sender, text, isCreatedByUser, error, submitting } = message; + const { sender, text, searchResult, isCreatedByUser, error, submitting } = message; const textEditor = useRef(null); const convo = useSelector((state) => state.convo); const last = !message?.children?.length; @@ -159,7 +159,7 @@ export default function Message({
{/*
*/}
- {!isCreatedByUser ? ( + {(!isCreatedByUser || searchResult) ? ( { state.messages = action.payload; - state.messageTree = buildTree(action.payload); + const groupAll = action.payload[0]?.searchResult; + if (groupAll) console.log('grouping all messages'); + state.messageTree = buildTree(action.payload, groupAll); }, setEmptyMessage: (state) => { state.messages = [ diff --git a/client/src/utils/buildTree.js b/client/src/utils/buildTree.js index a030509bca..673ccc70f1 100644 --- a/client/src/utils/buildTree.js +++ b/client/src/utils/buildTree.js @@ -1,17 +1,29 @@ -export default function buildTree(messages) { +export default function buildTree(messages, groupAll = false) { let messageMap = {}; let rootMessages = []; - // Traverse the messages array and store each element in messageMap. - messages.forEach(message => { - messageMap[message.messageId] = {...message, children: []}; + if (!groupAll) { + // Traverse the messages array and store each element in messageMap. + messages.forEach((message) => { + messageMap[message.messageId] = { ...message, children: [] }; - const parentMessage = messageMap[message.parentMessageId]; - if (parentMessage) - parentMessage.children.push(messageMap[message.messageId]); - else - rootMessages.push(messageMap[message.messageId]); + const parentMessage = messageMap[message.parentMessageId]; + if (parentMessage) parentMessage.children.push(messageMap[message.messageId]); + else rootMessages.push(messageMap[message.messageId]); + }); + + return rootMessages; + } + + // Group all messages into one tree + let parentId = messages[0].messageId; + messages.forEach((message, i) => { + if (i === 0) { + messageMap[parentId] = { ...message, children: [] }; + return; + } + messageMap[parentId].children.push({ ...message, children: [] }); }); - return rootMessages; -} \ No newline at end of file + return [messageMap[parentId]]; +}