setup message population on search

This commit is contained in:
Daniel Avila 2023-03-18 18:40:53 -04:00
parent 4197a92609
commit 4e6168d8fa
5 changed files with 47 additions and 23 deletions

View file

@ -9,7 +9,8 @@ const validateOptions = function (options) {
}; };
const createMeiliMongooseModel = function ({ index, indexName, client, attributesToIndex }) { 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 // MeiliMongooseModel is of type Mongoose.Model
class MeiliMongooseModel { class MeiliMongooseModel {
// Clear Meili index // Clear Meili index
@ -24,7 +25,7 @@ const createMeiliMongooseModel = function ({ index, indexName, client, attribute
static async resetIndex() { static async resetIndex() {
await this.clearMeiliIndex(); await this.clearMeiliIndex();
await client.createIndex(indexName, { primaryKey: attributesToIndex[0] }); await client.createIndex(indexName, { primaryKey });
} }
// Clear Meili index // Clear Meili index
// Push a mongoDB collection to 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 // Populate hits with content from mongodb
if (populate) { if (populate) {
// Find objects into mongodb matching `objectID` from Meili search // Find objects into mongodb matching `objectID` from Meili search
const query = {};
query[primaryKey] = { $in: _.map(data.hits, primaryKey) };
const hitsFromMongoose = await this.find( const hitsFromMongoose = await this.find(
{ query,
_id: { $in: _.map(data.hits, '_id') }
},
_.reduce( _.reduce(
this.schema.obj, this.schema.obj,
function (results, value, key) { function (results, value, key) {
return { ...results, [key]: 1 }; return { ...results, [key]: 1 };
}, },
{ _id: 1 } { _id: 1 }
) ),
); );
// Add additional data from mongodb into Meili search hits // Add additional data from mongodb into Meili search hits
const populatedHits = data.hits.map(function (hit) { const populatedHits = data.hits.map(function (hit) {
const originalHit = _.find(hitsFromMongoose, { const query = {};
_id: hit._id query[primaryKey] = hit[primaryKey];
}); const originalHit = _.find(hitsFromMongoose, query);
return { return {
...(originalHit ? originalHit.toJSON() : {}), ...(originalHit ? originalHit.toJSON() : {}),

View file

@ -46,4 +46,13 @@ router.get('/clear', async function (req, res) {
res.send('cleared'); 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; module.exports = router;

View file

@ -22,7 +22,7 @@ export default function Message({
(state) => state.submit (state) => state.submit
); );
const [abortScroll, setAbort] = useState(false); 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 textEditor = useRef(null);
const convo = useSelector((state) => state.convo); const convo = useSelector((state) => state.convo);
const last = !message?.children?.length; const last = !message?.children?.length;
@ -159,7 +159,7 @@ export default function Message({
<div className="flex min-h-[20px] flex-grow flex-col items-start gap-4 whitespace-pre-wrap"> <div className="flex min-h-[20px] flex-grow flex-col items-start gap-4 whitespace-pre-wrap">
{/* <div className={`${blinker ? 'result-streaming' : ''} markdown prose dark:prose-invert light w-full break-words`}> */} {/* <div className={`${blinker ? 'result-streaming' : ''} markdown prose dark:prose-invert light w-full break-words`}> */}
<div className="markdown prose dark:prose-invert light w-full break-words"> <div className="markdown prose dark:prose-invert light w-full break-words">
{!isCreatedByUser ? ( {(!isCreatedByUser || searchResult) ? (
<TextWrapper <TextWrapper
text={text} text={text}
generateCursor={generateCursor} generateCursor={generateCursor}

View file

@ -12,7 +12,9 @@ const currentSlice = createSlice({
reducers: { reducers: {
setMessages: (state, action) => { setMessages: (state, action) => {
state.messages = action.payload; 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) => { setEmptyMessage: (state) => {
state.messages = [ state.messages = [

View file

@ -1,17 +1,29 @@
export default function buildTree(messages) { export default function buildTree(messages, groupAll = false) {
let messageMap = {}; let messageMap = {};
let rootMessages = []; let rootMessages = [];
if (!groupAll) {
// Traverse the messages array and store each element in messageMap. // Traverse the messages array and store each element in messageMap.
messages.forEach(message => { messages.forEach((message) => {
messageMap[message.messageId] = {...message, children: []}; messageMap[message.messageId] = { ...message, children: [] };
const parentMessage = messageMap[message.parentMessageId]; const parentMessage = messageMap[message.parentMessageId];
if (parentMessage) if (parentMessage) parentMessage.children.push(messageMap[message.messageId]);
parentMessage.children.push(messageMap[message.messageId]); else rootMessages.push(messageMap[message.messageId]);
else
rootMessages.push(messageMap[message.messageId]);
}); });
return rootMessages; 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 [messageMap[parentId]];
} }