Skip to content

Commit

Permalink
🐛 fix: keyword search for chat history & sessions (lobehub#4725)
Browse files Browse the repository at this point in the history
* 🐛 fix: sql for keyword search

* 🐛 fix: display search topics in time mode

* 🐛 fix: keyword search on sessions

* 🧪 test: adjust tests to new keyword search
  • Loading branch information
cy948 authored Nov 19, 2024
1 parent c154cb5 commit 415d772
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 16 deletions.
42 changes: 38 additions & 4 deletions src/database/server/models/__tests__/session.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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');
Expand All @@ -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']);
Expand Down
53 changes: 43 additions & 10 deletions src/database/server/models/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down Expand Up @@ -281,20 +281,53 @@ 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),
),

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 []
}
}
7 changes: 6 additions & 1 deletion src/database/server/models/topic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
)
),
),
),
),
Expand Down
2 changes: 1 addition & 1 deletion src/store/chat/slices/topic/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 415d772

Please sign in to comment.