Memory search is the core operation in Memsolus. This page covers how to get the most relevant results using search modes, filters, pagination, and the feedback loop.
Search modes
The mode parameter controls how memories are matched to your query. Choose based on the type of information you are looking for.
| Mode | Best for | How it works |
|---|
hybrid | General-purpose retrieval — recommended default | Combines semantic similarity and keyword matching, re-ranked for best results |
semantic | Conceptual similarity, paraphrases, translated content | Matches by meaning, not exact words |
keyword | Exact names, IDs, specific terms, codes | BM25 full-text matching |
import { MemsolusClient } from '@memsolus/sdk';
const client = new MemsolusClient({
apiKey: process.env.MEMSOLUS_API_KEY,
workspaceId: process.env.MEMSOLUS_WORKSPACE_ID,
});
const hybrid = await client.memories.search({
query: 'what does the user prefer for backend development?',
userId: 'user_123',
mode: 'hybrid',
});
const semantic = await client.memories.search({
query: 'server-side programming technology choices',
userId: 'user_123',
mode: 'semantic',
});
const keyword = await client.memories.search({
query: 'project-alpha api-gateway',
userId: 'user_123',
mode: 'keyword',
});
Filtering results
Narrow results using filters. All filters can be combined.
Filter by user
Scope search to a specific user's memories:
const results = await client.memories.search({
query: 'programming language preferences',
userId: 'user_123',
});
Filter by categories
Return only memories tagged with specific categories:
const results = await client.memories.search({
query: 'tech preferences',
userId: 'user_123',
categories: ['tech-stack', 'preferences'],
});
Filter by priority
Return only memories at a given priority level:
const highPriority = await client.memories.search({
query: 'important constraints',
userId: 'user_123',
priority: 'HIGH',
});
Combining filters
const results = await client.memories.search({
query: 'database decisions',
userId: 'user_123',
categories: ['architecture', 'decisions'],
priority: 'HIGH',
mode: 'hybrid',
limit: 10,
});
Controlling result count
Use limit to control how many memories are returned. The maximum is determined by your plan.
const [topResult] = (await client.memories.search({
query: 'user timezone preference',
userId: 'user_123',
limit: 1,
})).data;
console.log(topResult?.content);
console.log(topResult?.score);
Understanding relevance scores
Each memory in a search result has a score field between 0.0 and 1.0:
const results = await client.memories.search({
query: 'preferred database',
userId: 'user_123',
});
for (const memory of results.data) {
if (memory.score > 0.8) {
} else if (memory.score > 0.5) {
} else {
}
}
Results are returned in descending score order. The first result is always the most relevant.
Paginating list results
For browsing all memories (not search-ranked), use client.memories.list with pagination:
async function getAllMemories(userId: string): Promise<Memory[]> {
const all: Memory[] = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const result = await client.memories.list({
userId,
page,
pageSize: 50,
});
all.push(...result.data);
hasMore = page < result.meta.totalPages;
page++;
}
return all;
}
Feedback loop
After using a memory in a conversation, submit feedback to improve future search quality. Positive feedback boosts a memory's retrieval score; negative feedback reduces it.
const results = await client.memories.search({
query: 'user project stack',
userId: 'user_123',
limit: 3,
});
const [best] = results.data;
await client.memories.feedback({
id: best.id,
signal: 'POSITIVE',
});
await client.memories.feedback({
id: results.data[1].id,
signal: 'NEGATIVE',
comment: 'User no longer uses this framework.',
});
Over time, consistent feedback makes search more accurate for each user.
Common patterns
Load context at conversation start
At the beginning of a session, load the structured knowledge profile instead of doing a broad search:
const profile = await client.knowledge.list({
userId: 'user_123',
merged: true,
});
const relevant = await client.memories.search({
query: userMessage,
userId: 'user_123',
mode: 'hybrid',
limit: 5,
});
Search before storing
Before storing a new memory, search for existing ones to avoid duplicates:
const existing = await client.memories.search({
query: newFact,
userId: 'user_123',
limit: 3,
mode: 'semantic',
});
const isDuplicate = existing.data.some((m) => m.score > 0.92);
if (isDuplicate) {
await client.memories.update({
id: existing.data[0].id,
content: newFact,
});
} else {
await client.memories.create({
content: newFact,
userId: 'user_123',
});
}
- Memories — full reference for
create, list, feedback, and other methods
- Knowledge — structured profile built from memories, ideal for conversation start
- Type Reference —
SearchResult, SearchMode, Memory, and related types