AI Skill Library

Elasticsearch

Index, mapping, full-text search, aggregations, filters, relevance tuning.

elasticsearchsearchbackenddatabase
# Elasticsearch

## Run (Docker)
```bash
docker run -d --name es \
  -e discovery.type=single-node \
  -e xpack.security.enabled=false \
  -p 9200:9200 \
  elasticsearch:8.13.0
```

## Index & mapping
```bash
# Create index with mapping
curl -X PUT http://localhost:9200/articles -H 'Content-Type: application/json' -d '{
  "mappings": {
    "properties": {
      "title":     { "type": "text", "analyzer": "ik_max_word" },
      "content":  { "type": "text", "analyzer": "ik_max_word" },
      "tags":     { "type": "keyword" },
      "author":   { "type": "keyword" },
      "publishedAt": { "type": "date" },
      "views":    { "type": "integer" }
    }
  }
}'
```

## Node.js client
```bash
npm install @elastic/elasticsearch
```
```ts
import { Client } from '@elastic/elasticsearch'
const es = new Client({ node: 'http://localhost:9200' })

// Index document
await es.index({
  index: 'articles',
  id: '1',
  document: { title: 'Hello', content: 'World', tags: ['tech'], publishedAt: new Date() },
})

// Bulk index
await es.bulk({
  operations: docs.flatMap(doc => [{ index: { _index: 'articles' } }, doc]),
})
await es.indices.refresh({ index: 'articles' })
```

## Search queries
```ts
// Full-text search
const { hits } = await es.search({
  index: 'articles',
  query: {
    multi_match: {
      query: 'elasticsearch tutorial',
      fields: ['title^3', 'content'],  // ^3 boosts title
      type: 'best_fields',
      fuzziness: 'AUTO',
    },
  },
  highlight: { fields: { content: {} } },
  from: 0, size: 10,
})
console.log(hits.hits.map(h => ({ id: h._id, score: h._score, ...h._source })))

// Bool query (must + filter + should)
const result = await es.search({
  index: 'articles',
  query: {
    bool: {
      must:   [{ match: { content: 'javascript' } }],
      filter: [
        { term: { tags: 'frontend' } },
        { range: { publishedAt: { gte: '2024-01-01' } } },
      ],
      should: [{ term: { author: 'alice' } }],
      minimum_should_match: 0,
    },
  },
})
```

## Aggregations
```ts
const result = await es.search({
  index: 'articles',
  size: 0,  // no documents, only aggs
  aggs: {
    by_tag: { terms: { field: 'tags', size: 10 } },
    avg_views: { avg: { field: 'views' } },
    over_time: {
      date_histogram: { field: 'publishedAt', calendar_interval: 'month' },
    },
  },
})
```

## Chinese analyzer (IK)
```bash
docker exec es bin/elasticsearch-plugin install \
  https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.13.0/elasticsearch-analysis-ik-8.13.0.zip
```
Analyzers: `ik_max_word` (split into smallest terms), `ik_smart` (split into meaningful phrases)

## Index management
```bash
# Delete & recreate for reindex
curl -X DELETE http://localhost:9200/articles
# Aliases for zero-downtime reindex
curl -X POST http://localhost:9200/_aliases -d '{"actions":[{"add":{"index":"articles_v2","alias":"articles"}}]}'
```

API: /api/skills/elasticsearch