337 lines
7.8 KiB
Markdown
337 lines
7.8 KiB
Markdown
# 🔍 Meilisearch Setup Guide
|
|
|
|
Complete guide for testing and using the Meilisearch integration in ObsiViewer.
|
|
|
|
## Quick Start (5 minutes)
|
|
|
|
### 1. Start Meilisearch
|
|
|
|
```bash
|
|
npm run meili:up
|
|
```
|
|
|
|
This launches Meilisearch in Docker on port 7700.
|
|
|
|
### 2. Index Your Vault
|
|
|
|
```bash
|
|
npm run meili:reindex
|
|
```
|
|
|
|
This indexes all `.md` files from your vault. Progress will be logged to console.
|
|
|
|
### 3. Test the API
|
|
|
|
```bash
|
|
# Simple search
|
|
curl "http://localhost:4000/api/search?q=obsidian"
|
|
|
|
# With operators
|
|
curl "http://localhost:4000/api/search?q=tag:work path:Projects"
|
|
|
|
# All notes
|
|
curl "http://localhost:4000/api/search?q=*&limit=5"
|
|
```
|
|
|
|
### 4. Enable in Angular (Optional)
|
|
|
|
Edit `src/core/logging/environment.ts`:
|
|
|
|
```typescript
|
|
export const environment = {
|
|
USE_MEILI: true, // ← Change this to true
|
|
// ...
|
|
};
|
|
```
|
|
|
|
Then restart your Angular dev server: `npm run dev`
|
|
|
|
## Testing Checklist
|
|
|
|
### ✅ Backend Tests
|
|
|
|
- [ ] **Docker started**: `docker ps` shows `obsiviewer-meilisearch` running
|
|
- [ ] **Indexing works**: `npm run meili:reindex` completes without errors
|
|
- [ ] **Basic search**: `curl "http://localhost:4000/api/search?q=*"` returns hits
|
|
- [ ] **Tag filter**: `curl "http://localhost:4000/api/search?q=tag:yourTag"` works
|
|
- [ ] **Path filter**: `curl "http://localhost:4000/api/search?q=path:YourFolder"` works
|
|
- [ ] **File filter**: `curl "http://localhost:4000/api/search?q=file:readme"` works
|
|
- [ ] **Highlights**: Response includes `_formatted` with `<mark>` tags
|
|
- [ ] **Facets**: Response includes `facetDistribution` with tags, parentDirs
|
|
- [ ] **Performance**: `npm run bench:search` shows P95 < 150ms
|
|
|
|
### ✅ Incremental Updates
|
|
|
|
Test that Chokidar automatically updates Meilisearch:
|
|
|
|
1. Start server: `node server/index.mjs`
|
|
2. Create a new `.md` file in vault with tag `#test-meilisearch`
|
|
3. Search: `curl "http://localhost:4000/api/search?q=tag:test-meilisearch"`
|
|
4. Verify the new file appears in results
|
|
5. Edit the file, search again - changes should be reflected
|
|
6. Delete the file, search again - should no longer appear
|
|
|
|
### ✅ Angular Integration
|
|
|
|
With `USE_MEILI: true`:
|
|
|
|
1. Open app in browser: `http://localhost:4200`
|
|
2. Use search bar
|
|
3. Open browser DevTools Network tab
|
|
4. Verify requests go to `/api/search` instead of local search
|
|
5. Results should show server-side highlights
|
|
|
|
## Query Examples
|
|
|
|
### Basic Searches
|
|
|
|
```bash
|
|
# Find all notes
|
|
curl "http://localhost:4000/api/search?q=*"
|
|
|
|
# Simple text search
|
|
curl "http://localhost:4000/api/search?q=obsidian"
|
|
|
|
# Phrase search
|
|
curl "http://localhost:4000/api/search?q=search%20engine"
|
|
```
|
|
|
|
### Operators
|
|
|
|
```bash
|
|
# Single tag
|
|
curl "http://localhost:4000/api/search?q=tag:dev"
|
|
|
|
# Multiple tags (both must match)
|
|
curl "http://localhost:4000/api/search?q=tag:dev tag:angular"
|
|
|
|
# Path filter
|
|
curl "http://localhost:4000/api/search?q=path:Projects/Angular"
|
|
|
|
# File name search
|
|
curl "http://localhost:4000/api/search?q=file:readme"
|
|
|
|
# Combined: tag + path + text
|
|
curl "http://localhost:4000/api/search?q=tag:dev path:Projects typescript"
|
|
```
|
|
|
|
### Typo Tolerance
|
|
|
|
```bash
|
|
# Intentional typos (should still match)
|
|
curl "http://localhost:4000/api/search?q=obsever" # → "observer"
|
|
curl "http://localhost:4000/api/search?q=searh" # → "search"
|
|
```
|
|
|
|
### Pagination & Sorting
|
|
|
|
```bash
|
|
# Limit results
|
|
curl "http://localhost:4000/api/search?q=*&limit=10"
|
|
|
|
# Offset (page 2)
|
|
curl "http://localhost:4000/api/search?q=*&limit=10&offset=10"
|
|
|
|
# Sort by date (newest first)
|
|
curl "http://localhost:4000/api/search?q=*&sort=updatedAt:desc"
|
|
|
|
# Sort by title
|
|
curl "http://localhost:4000/api/search?q=*&sort=title:asc"
|
|
```
|
|
|
|
## Performance Benchmarking
|
|
|
|
Run the benchmark suite:
|
|
|
|
```bash
|
|
npm run bench:search
|
|
```
|
|
|
|
This tests 5 different queries with 20 concurrent connections for 10 seconds each.
|
|
|
|
**Expected Results** (on modern dev machine with 1000 notes):
|
|
- P95: < 150ms ✅
|
|
- Average: 50-100ms
|
|
- Throughput: 200+ req/sec
|
|
|
|
If P95 exceeds 150ms, check:
|
|
1. Is Meilisearch running? `docker ps`
|
|
2. Is the index populated? Check `/health` endpoint
|
|
3. System resources (CPU/RAM)
|
|
4. Adjust `typoTolerance` or `searchableAttributes` in `meilisearch.client.mjs`
|
|
|
|
## Troubleshooting
|
|
|
|
### Meilisearch won't start
|
|
|
|
```bash
|
|
# Check if port 7700 is already in use
|
|
netstat -an | findstr 7700 # Windows
|
|
lsof -i :7700 # macOS/Linux
|
|
|
|
# View Meilisearch logs
|
|
docker logs obsiviewer-meilisearch
|
|
|
|
# Restart Meilisearch
|
|
npm run meili:down
|
|
npm run meili:up
|
|
```
|
|
|
|
### Search returns empty results
|
|
|
|
```bash
|
|
# Check if index exists and has documents
|
|
curl http://localhost:7700/indexes/notes_vault/stats \
|
|
-H "Authorization: Bearer dev_meili_master_key_change_me"
|
|
|
|
# Reindex if needed
|
|
npm run meili:reindex
|
|
```
|
|
|
|
### "Connection refused" errors
|
|
|
|
Ensure Meilisearch is running:
|
|
|
|
```bash
|
|
docker ps | grep meilisearch
|
|
# Should show: obsiviewer-meilisearch ... Up ... 0.0.0.0:7700->7700/tcp
|
|
```
|
|
|
|
### Changes not reflected immediately
|
|
|
|
Wait 1-2 seconds after file changes for Chokidar to process. Check server logs:
|
|
|
|
```
|
|
[Meili] Upserted: Projects/MyNote.md
|
|
```
|
|
|
|
### Performance issues
|
|
|
|
1. **Reduce typo tolerance**: Edit `server/meilisearch.client.mjs`
|
|
```javascript
|
|
typoTolerance: {
|
|
enabled: true,
|
|
minWordSizeForTypos: {
|
|
oneTypo: 5, // Was 3
|
|
twoTypos: 9 // Was 6
|
|
}
|
|
}
|
|
```
|
|
|
|
2. **Limit searchable attributes**: Remove `headings` or `properties.*` if not needed
|
|
|
|
3. **Increase batch size**: Edit `server/meilisearch-indexer.mjs`
|
|
```javascript
|
|
const batchSize = 1000; // Was 750
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
### Development (local)
|
|
|
|
`.env` or shell:
|
|
```bash
|
|
VAULT_PATH=./vault
|
|
MEILI_HOST=http://127.0.0.1:7700
|
|
MEILI_API_KEY=dev_meili_master_key_change_me
|
|
```
|
|
|
|
### Docker Compose
|
|
|
|
`docker-compose/.env`:
|
|
```env
|
|
MEILI_MASTER_KEY=dev_meili_master_key_change_me
|
|
MEILI_ENV=development
|
|
```
|
|
|
|
### Production
|
|
|
|
**Important**: Change the master key in production!
|
|
|
|
```bash
|
|
MEILI_MASTER_KEY=$(openssl rand -base64 32)
|
|
MEILI_ENV=production
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### GET /api/search
|
|
|
|
**Query Parameters**:
|
|
- `q` (string, required): Search query with optional operators
|
|
- `limit` (number, default: 20): Max results to return
|
|
- `offset` (number, default: 0): Pagination offset
|
|
- `sort` (string): Sort field and direction, e.g., `updatedAt:desc`
|
|
- `highlight` (boolean, default: true): Include `<mark>` highlights
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"hits": [
|
|
{
|
|
"id": "Projects/MyNote.md",
|
|
"title": "My Note",
|
|
"path": "Projects/MyNote.md",
|
|
"file": "MyNote.md",
|
|
"tags": ["dev", "typescript"],
|
|
"excerpt": "First 500 chars...",
|
|
"_formatted": {
|
|
"title": "My <mark>Note</mark>",
|
|
"content": "...search <mark>term</mark>..."
|
|
}
|
|
}
|
|
],
|
|
"estimatedTotalHits": 42,
|
|
"facetDistribution": {
|
|
"tags": { "dev": 15, "typescript": 8 },
|
|
"parentDirs": { "Projects": 42 }
|
|
},
|
|
"processingTimeMs": 12,
|
|
"query": "note"
|
|
}
|
|
```
|
|
|
|
### POST /api/reindex
|
|
|
|
Triggers a full reindex of all markdown files in the vault.
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"ok": true,
|
|
"indexed": true,
|
|
"count": 1247,
|
|
"elapsedMs": 3421
|
|
}
|
|
```
|
|
|
|
## Next Steps
|
|
|
|
### P1 Features (Future)
|
|
|
|
- [ ] Multi-language support (configure `locale` in Meilisearch)
|
|
- [ ] Synonyms configuration
|
|
- [ ] Stop words for common terms
|
|
- [ ] Advanced operators: `line:`, `section:`, `[property]:value`
|
|
- [ ] Faceted search UI (tag/folder selectors)
|
|
- [ ] Search result pagination in Angular
|
|
- [ ] Search analytics and logging
|
|
- [ ] Incremental indexing optimization (delta updates)
|
|
|
|
### Performance Optimization
|
|
|
|
- [ ] Redis cache layer for frequent queries
|
|
- [ ] CDN for static assets
|
|
- [ ] Index sharding for very large vaults (10k+ notes)
|
|
- [ ] Lazy loading of highlights (fetch on demand)
|
|
|
|
## Support
|
|
|
|
If you encounter issues:
|
|
|
|
1. Check server logs: `node server/index.mjs` (console output)
|
|
2. Check Meilisearch logs: `docker logs obsiviewer-meilisearch`
|
|
3. Verify environment variables are set correctly
|
|
4. Ensure vault path is correct and contains `.md` files
|
|
5. Test with curl before testing in Angular
|