From eb3bc94e0d2262af4926b68c997c0607473cf949 Mon Sep 17 00:00:00 2001 From: cy948 Date: Sun, 17 Nov 2024 23:46:58 +0800 Subject: [PATCH 1/4] :bug: fix: sql for keyword search --- src/database/server/models/topic.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/database/server/models/topic.ts b/src/database/server/models/topic.ts index 7dac6002baf33..128bd2d801aa2 100644 --- a/src/database/server/models/topic.ts +++ b/src/database/server/models/topic.ts @@ -85,7 +85,12 @@ export class TopicModel { serverDB .select() .from(messages) - .where(and(eq(messages.topicId, topics.id), or(matchKeyword(messages.content)))), + .where( + and( + eq(messages.topicId, topics.id), + matchKeyword(messages.content) + ) + ), ), ), ), From c23eeef8268c8cc5771bf80f01303ff58813507c Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 18 Nov 2024 09:37:28 +0800 Subject: [PATCH 2/4] :bug: fix: display search topics in time mode --- src/store/chat/slices/topic/selectors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/chat/slices/topic/selectors.ts b/src/store/chat/slices/topic/selectors.ts index a05d4deba7109..07d54dcf535d1 100644 --- a/src/store/chat/slices/topic/selectors.ts +++ b/src/store/chat/slices/topic/selectors.ts @@ -42,7 +42,7 @@ const currentActiveTopicSummary = (s: ChatStoreState): ChatTopicSummary | undefi const isCreatingTopic = (s: ChatStoreState) => s.creatingTopic; const groupedTopicsSelector = (s: ChatStoreState): GroupedTopic[] => { - const topics = currentTopics(s); + const topics = displayTopics(s); if (!topics) return []; const favTopics = currentFavTopics(s); From 2536960825cb4bebe24f4a33f223d75b5e7bdc8c Mon Sep 17 00:00:00 2001 From: cy948 Date: Mon, 18 Nov 2024 18:59:45 +0800 Subject: [PATCH 3/4] :bug: fix: keyword search on sessions --- src/database/server/models/session.ts | 53 ++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/src/database/server/models/session.ts b/src/database/server/models/session.ts index 136104da2ead6..01d4bb287d868 100644 --- a/src/database/server/models/session.ts +++ b/src/database/server/models/session.ts @@ -61,7 +61,7 @@ export class SessionModel { const keywordLowerCase = keyword.toLowerCase(); - const data = await this.findSessions({ keyword: keywordLowerCase }); + const data = await this.findSessionsByKeywords({ keyword: keywordLowerCase }); return data.map((item) => this.mapSessionItem(item as any)); } @@ -281,15 +281,15 @@ export class SessionModel { pinned !== undefined ? eq(sessions.pinned, pinned) : eq(sessions.userId, this.userId), keyword ? or( - like( - sql`lower(${sessions.title})` as unknown as Column, - `%${keyword.toLowerCase()}%`, - ), - like( - sql`lower(${sessions.description})` as unknown as Column, - `%${keyword.toLowerCase()}%`, - ), - ) + like( + sql`lower(${sessions.title})` as unknown as Column, + `%${keyword.toLowerCase()}%`, + ), + like( + sql`lower(${sessions.description})` as unknown as Column, + `%${keyword.toLowerCase()}%`, + ), + ) : eq(sessions.userId, this.userId), group ? eq(sessions.groupId, group) : isNull(sessions.groupId), ), @@ -297,4 +297,37 @@ export class SessionModel { with: { agentsToSessions: { columns: {}, with: { agent: true } }, group: true }, }); } + + async findSessionsByKeywords(params: { + current?: number; + keyword: string; + pageSize?: number; + }) { + const { keyword, pageSize = 9999, current = 0 } = params; + const offset = current * pageSize; + const results = await serverDB.query.agents.findMany({ + limit: pageSize, + offset, + orderBy: [desc(agents.updatedAt)], + where: and( + eq(agents.userId, this.userId), + or( + like( + sql`lower(${agents.title})` as unknown as Column, + `%${keyword.toLowerCase()}%`, + ), + like( + sql`lower(${agents.description})` as unknown as Column, + `%${keyword.toLowerCase()}%`, + ), + ) + ), + with: { agentsToSessions: { columns: {}, with: { session: true } } }, + }); + try { + // @ts-expect-error + return results.map((item) => item.agentsToSessions[0].session); + } catch {} + return [] + } } From 6a0d71d68f5770627804087a020ededb87ed2699 Mon Sep 17 00:00:00 2001 From: cy948 Date: Tue, 19 Nov 2024 10:38:41 +0800 Subject: [PATCH 4/4] :test_tube: test: adjust tests to new keyword search --- .../server/models/__tests__/session.test.ts | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/database/server/models/__tests__/session.test.ts b/src/database/server/models/__tests__/session.test.ts index 4d128e5be37ec..0a91adb6f7f86 100644 --- a/src/database/server/models/__tests__/session.test.ts +++ b/src/database/server/models/__tests__/session.test.ts @@ -231,8 +231,18 @@ describe('SessionModel', () => { it('should return sessions with matching title', async () => { await serverDB.insert(sessions).values([ - { id: '1', userId, title: 'Hello World', description: 'Some description' }, - { id: '2', userId, title: 'Another Session', description: 'Another description' }, + { id: '1', userId }, + { id: '2', userId }, + ]); + + await serverDB.insert(agents).values([ + { id: 'agent-1', userId, model: 'gpt-3.5-turbo', title: 'Hello, Agent 1' }, + { id: 'agent-2', userId, model: 'gpt-4', title: 'Agent 2' }, + ]); + + await serverDB.insert(agentsToSessions).values([ + { agentId: 'agent-1', sessionId: '1' }, + { agentId: 'agent-2', sessionId: '2' }, ]); const result = await sessionModel.queryByKeyword('hello'); @@ -241,9 +251,21 @@ describe('SessionModel', () => { }); it('should return sessions with matching description', async () => { + // The sessions has no title and desc, + // see: https://github.com/lobehub/lobe-chat/pull/4725 await serverDB.insert(sessions).values([ - { id: '1', userId, title: 'Session 1', description: 'Description with keyword' }, - { id: '2', userId, title: 'Session 2', description: 'Another description' }, + { id: '1', userId }, + { id: '2', userId }, + ]); + + await serverDB.insert(agents).values([ + { id: 'agent-1', userId, model: 'gpt-3.5-turbo', title: 'Agent 1', description: 'Description with Keyword' }, + { id: 'agent-2', userId, model: 'gpt-4', title: 'Agent 2' }, + ]); + + await serverDB.insert(agentsToSessions).values([ + { agentId: 'agent-1', sessionId: '1' }, + { agentId: 'agent-2', sessionId: '2' }, ]); const result = await sessionModel.queryByKeyword('keyword'); @@ -253,11 +275,23 @@ describe('SessionModel', () => { it('should return sessions with matching title or description', async () => { await serverDB.insert(sessions).values([ + { id: '1', userId }, + { id: '2', userId }, + { id: '3', userId }, + ]); + + await serverDB.insert(agents).values([ { id: '1', userId, title: 'Title with keyword', description: 'Some description' }, { id: '2', userId, title: 'Another Session', description: 'Description with keyword' }, { id: '3', userId, title: 'Third Session', description: 'Third description' }, ]); + await serverDB.insert(agentsToSessions).values([ + { agentId: '1', sessionId: '1' }, + { agentId: '2', sessionId: '2' }, + { agentId: '3', sessionId: '3' }, + ]); + const result = await sessionModel.queryByKeyword('keyword'); expect(result).toHaveLength(2); expect(result.map((s) => s.id)).toEqual(['1', '2']);