From 4fd05e15b4b6350382c76f2b84d58b342efa8fdf Mon Sep 17 00:00:00 2001 From: Daniel Avila Date: Mon, 13 Mar 2023 21:59:25 -0400 Subject: [PATCH] fix: migrate old schema to new --- api/models/Conversation.js | 135 ++++++++++++++++++++++++--------- api/models/Message.js | 2 +- api/models/index.js | 3 +- api/server/index.js | 6 +- api/server/routes/askBing.js | 2 +- api/server/routes/askSydney.js | 2 +- 6 files changed, 108 insertions(+), 42 deletions(-) diff --git a/api/models/Conversation.js b/api/models/Conversation.js index c8daf78c4a..1c994fdc38 100644 --- a/api/models/Conversation.js +++ b/api/models/Conversation.js @@ -1,44 +1,48 @@ const mongoose = require('mongoose'); +const crypto = require('crypto'); const { getMessages, deleteMessages } = require('./Message'); -const convoSchema = mongoose.Schema({ - conversationId: { - type: String, - unique: true, - required: true +const convoSchema = mongoose.Schema( + { + conversationId: { + type: String, + unique: true, + required: true + }, + parentMessageId: { + type: String, + required: true + }, + title: { + type: String, + default: 'New Chat' + }, + jailbreakConversationId: { + type: String + }, + conversationSignature: { + type: String + }, + clientId: { + type: String + }, + invocationId: { + type: String + }, + chatGptLabel: { + type: String + }, + promptPrefix: { + type: String + }, + model: { + type: String + }, + suggestions: [{ type: String }], + messages: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Message' }] }, - parentMessageId: { - type: String, - required: true - }, - title: { - type: String, - default: 'New Chat' - }, - jailbreakConversationId: { - type: String - }, - conversationSignature: { - type: String - }, - clientId: { - type: String - }, - invocationId: { - type: String - }, - chatGptLabel: { - type: String - }, - promptPrefix: { - type: String - }, - model: { - type: String - }, - suggestions: [{ type: String }], - messages: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Message' }], -}, { timestamps: true }); + { timestamps: true } +); const Conversation = mongoose.models.Conversation || mongoose.model('Conversation', convoSchema); @@ -114,5 +118,62 @@ module.exports = { let deleteCount = await Conversation.deleteMany(filter).exec(); deleteCount.messages = await deleteMessages(filter); return deleteCount; + }, + migrateDb: async () => { + try { + const conversations = await Conversation.find({ model: null }).exec(); + + if (!conversations || conversations.length === 0) + return { message: 'No conversations to migrate' }; + + for (let convo of conversations) { + const messages = await getMessages({ + conversationId: convo.conversationId, + messageId: { $exists: false } + }); + + const promises = []; + let model; + let oldId; + messages.forEach((message, i) => { + const msgObj = message.toObject(); + const newId = msgObj.id; + if (i === 0) { + message.parentMessageId = '00000000-0000-0000-0000-000000000000'; + oldId = newId; + } else { + message.parentMessageId = oldId; + oldId = newId; + } + + message.messageId = newId; + message.createdAt = message.created; + if (message.sender.toLowerCase() !== 'user' && !model) { + model = message.sender.toLowerCase(); + } + + if (message.sender.toLowerCase() === 'user') { + message.isCreatedByUser = true; + } + promises.push(message.save()); + }); + await Promise.all(promises); + + await Conversation.findOneAndUpdate( + { conversationId: convo.conversationId }, + { model, createdAt: convo.created }, + { new: true } + ).exec(); + } + + try { + await mongoose.connection.db.collection('messages').dropIndex('id_1'); + } catch (error) { + console.log("Index doesn't exist or already dropped"); + } + } catch (error) { + console.log(error); + return { message: 'Error migrating conversations' }; + } } }; diff --git a/api/models/Message.js b/api/models/Message.js index 9e281a9f16..90165acb86 100644 --- a/api/models/Message.js +++ b/api/models/Message.js @@ -64,7 +64,7 @@ module.exports = { }, deleteMessagesSince: async ({ messageId, conversationId }) => { try { - message = await Message.findOne({ messageId }).exec() + const message = await Message.findOne({ messageId }).exec() if (message) return await Message.find({ conversationId }).deleteMany({ createdAt: { $gt: message.createdAt } }).exec(); diff --git a/api/models/index.js b/api/models/index.js index 4ed1285bbf..cd75b9c6a3 100644 --- a/api/models/index.js +++ b/api/models/index.js @@ -1,6 +1,6 @@ const { saveMessage, deleteMessagesSince, deleteMessages } = require('./Message'); const { getCustomGpts, updateCustomGpt, updateByLabel, deleteCustomGpts } = require('./CustomGpt'); -const { getConvoTitle, getConvo, saveConvo } = require('./Conversation'); +const { getConvoTitle, getConvo, saveConvo, migrateDb } = require('./Conversation'); module.exports = { saveMessage, @@ -9,6 +9,7 @@ module.exports = { getConvoTitle, getConvo, saveConvo, + migrateDb, getCustomGpts, updateCustomGpt, updateByLabel, diff --git a/api/server/index.js b/api/server/index.js index b380932531..bda88b14f4 100644 --- a/api/server/index.js +++ b/api/server/index.js @@ -1,5 +1,6 @@ const express = require('express'); const dbConnect = require('../models/dbConnect'); +const { migrateDb } = require('../models'); const path = require('path'); const cors = require('cors'); const routes = require('./routes'); @@ -7,7 +8,10 @@ const app = express(); const port = process.env.PORT || 3080; const host = process.env.HOST || 'localhost' const projectPath = path.join(__dirname, '..', '..', 'client'); -dbConnect().then(() => console.log('Connected to MongoDB')); +dbConnect().then(() => { + console.log('Connected to MongoDB'); + migrateDb(); +}); app.use(cors()); app.use(express.json()); diff --git a/api/server/routes/askBing.js b/api/server/routes/askBing.js index 7b5ca44185..8c8238917a 100644 --- a/api/server/routes/askBing.js +++ b/api/server/routes/askBing.js @@ -14,7 +14,7 @@ router.post('/', async (req, res) => { const conversationId = oldConversationId || crypto.randomUUID(); - const userMessageId = messageId; + const userMessageId = crypto.randomUUID(); const userParentMessageId = parentMessageId || '00000000-0000-0000-0000-000000000000' let userMessage = { messageId: userMessageId, diff --git a/api/server/routes/askSydney.js b/api/server/routes/askSydney.js index cdf571fbfe..8738b625d0 100644 --- a/api/server/routes/askSydney.js +++ b/api/server/routes/askSydney.js @@ -14,7 +14,7 @@ router.post('/', async (req, res) => { const conversationId = oldConversationId || crypto.randomUUID(); - const userMessageId = messageId; + const userMessageId = crypto.randomUUID(); const userParentMessageId = parentMessageId || '00000000-0000-0000-0000-000000000000' let userMessage = { messageId: userMessageId,