Guides
Learn how to search your documents using semantic similarity to find relevant information.
Semantic search finds information based on meaning, not just exact keywords. This means:
Unlike traditional keyword search, semantic search understands context and intent.
When you search:
bashcurl -X POST https://api.easyrag.com/v1/search \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "datasetId": "my-documents", "question": "What are the key features?" }'
javascriptconst response = await fetch('https://api.easyrag.com/v1/search', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ datasetId: 'my-documents', question: 'What are the key features?' }) }); const { data } = await response.json(); console.log('Found', data.length, 'results');
From a backend or serverless function you can use the SDK instead of calling the HTTP API directly:
tsimport { EasyRAG } from "@easyrag/sdk"; const client = new EasyRAG({ apiKey: process.env.EASY_RAG_KEY! }); const results = await client.search("my-documents", "What are the key features?", { filters: [], // optional }); console.log("Found", results.data.length, "results");
json{ "success": true, "data": [ { "score": 0.892, "pageContent": "The key features include automatic document processing, semantic search, and AI-powered answers...", "metadata": { "fileId": "f7a3b2c1-4d5e", "originalName": "features.pdf", "datasetId": "my-documents" } }, { "score": 0.856, "pageContent": "Our platform offers three main capabilities: document upload, intelligent search, and question answering...", "metadata": { "fileId": "a1b2c3d4-5e6f", "originalName": "overview.pdf", "datasetId": "my-documents" } } ] }
The score field indicates relevance (0-1):
The actual text chunk from your document:
javascriptresult.pageContent // "The key features include automatic document processing..."
This is typically 200-400 words (depending on your chunk size).
Information about the source document:
javascriptresult.metadata // { // fileId: "f7a3b2c1-4d5e", // originalName: "features.pdf", // datasetId: "my-documents", // // ... any custom metadata you added during upload // }
Use metadata filters to narrow your search:
javascriptconst response = await fetch('https://api.easyrag.com/v1/search', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ datasetId: 'company-docs', question: 'vacation policy', filters: [ { key: 'department', match: { value: 'HR' } }, { key: 'year', match: { value: 2024 } } ] }) });
This searches only within HR documents from 2024.
See Filtering with Metadata for more details.
javascriptasync function searchWithRetry(datasetId, question, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { const response = await fetch('https://api.easyrag.com/v1/search', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ datasetId, question }) }); if (response.ok) { return await response.json(); } // Retry on 500 errors if (response.status === 500 && i < maxRetries - 1) { await new Promise(r => setTimeout(r, 1000 * (i + 1))); continue; } throw new Error(`Search failed: ${response.status}`); } catch (error) { if (i === maxRetries - 1) throw error; } } }
javascriptfunction highlightText(text, query) { const words = query.toLowerCase().split(' '); let highlighted = text; words.forEach(word => { const regex = new RegExp(`(${word})`, 'gi'); highlighted = highlighted.replace( regex, '<mark>$1</mark>' ); }); return highlighted; } // Usage <div dangerouslySetInnerHTML={{ __html: highlightText(result.pageContent, query) }} />
javascriptfunction groupByFile(results) { const grouped = {}; results.forEach(result => { const fileName = result.metadata.originalName; if (!grouped[fileName]) { grouped[fileName] = []; } grouped[fileName].push(result); }); return grouped; } // Usage const grouped = groupByFile(results); Object.entries(grouped).forEach(([fileName, chunks]) => { console.log(`${fileName}: ${chunks.length} matches`); });
Help users find relevant documents:
javascriptconst results = await search('company-docs', 'meeting notes from last week'); const files = [...new Set(results.map(r => r.metadata.originalName))]; console.log('Relevant documents:', files);
Build a self-service help center:
javascriptconst results = await search('help-docs', 'how to reset password'); // Show top result as "best answer" const bestMatch = results[0]; if (bestMatch.score > 0.8) { console.log('Answer:', bestMatch.pageContent); }
Search only a user's documents:
javascriptawait search('shared-dataset', query, { filters: [ { key: 'userId', match: { value: currentUserId } } ] });
Use /v1/search when:
Use /v1/query when:
See Asking Questions for the query endpoint.
javascript// ✅ Good: Natural language "How do I reset my password?" "What are the refund policies?" "Explain the installation process" // ❌ Bad: Keywords only "password reset" "refund" "install"
Natural language gives better results because embeddings understand context.
javascriptconst { data } = await search(datasetId, question); if (data.length === 0) { console.log('No results found. Try different keywords.'); } else if (data[0].score < 0.7) { console.log('Results may not be very relevant.'); }
Always show users where results came from:
javascript{results.map(r => ( <div key={r.metadata.fileId}> <small>From: {r.metadata.originalName}</small> <p>{r.pageContent}</p> </div> ))}
javascript// ✅ Good: Filter by user await search('shared-docs', query, { filters: [{ key: 'userId', match: { value: userId } }] }); // ❌ Bad: No filtering - shows all users' data await search('shared-docs', query);
Each search costs 0.1 credit (same as query).
| Operation | Cost |
|---|---|
| 1 search | 0.1 credit |
| 10 searches | 1 credit |
| 100 searches | 10 credits |
Problem: Search returns empty array
Solutions:
GET /v1/filesProblem: All results have scores below 0.7
Solutions:
Problem: Results don't match the question
Solutions:
For technical details, see Search API Reference.