- Elasticsearch 8.x dans docker-compose.dev - Package internal/elasticsearch: client, config, mappings, indices - Sync PG→ES: reindex tracks/users/playlists, IndexTrack/DeleteTrack - SearchService ES: multi_match + fuzziness (typo tolerance), highlighting - Fallback gracieux: PostgreSQL si ELASTICSEARCH_URL absent - Routes: GET /search, GET /search/suggestions, POST /admin/search/reindex - Frontend: searchApi cursor/limit params (extensibilité) - docs/ENV_VARIABLES: ELASTICSEARCH_URL, ELASTICSEARCH_INDEX, ELASTICSEARCH_AUTO_INDEX - Roadmap v0.10.2 → DONE
50 lines
1.2 KiB
Go
50 lines
1.2 KiB
Go
package elasticsearch
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/elastic/go-elasticsearch/v8"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// Client wraps Elasticsearch client with health check (v0.10.2 F361)
|
|
type Client struct {
|
|
*elasticsearch.Client
|
|
Config Config
|
|
Logger *zap.Logger
|
|
}
|
|
|
|
// NewClient creates Elasticsearch client when ELASTICSEARCH_URL is set
|
|
func NewClient(cfg Config, logger *zap.Logger) (*Client, error) {
|
|
if !cfg.Enabled {
|
|
return nil, nil
|
|
}
|
|
es, err := elasticsearch.NewClient(elasticsearch.Config{
|
|
Addresses: []string{cfg.URL},
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("elasticsearch: create client: %w", err)
|
|
}
|
|
c := &Client{Client: es, Config: cfg, Logger: logger}
|
|
if err := c.Ping(context.Background()); err != nil {
|
|
return nil, fmt.Errorf("elasticsearch: ping: %w", err)
|
|
}
|
|
if logger != nil {
|
|
logger.Info("Elasticsearch client connected", zap.String("url", cfg.URL), zap.String("index", cfg.Index))
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
// Ping checks Elasticsearch cluster health
|
|
func (c *Client) Ping(ctx context.Context) error {
|
|
res, err := c.Info(c.Info.WithContext(ctx))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer res.Body.Close()
|
|
if res.IsError() {
|
|
return fmt.Errorf("elasticsearch info failed: %s", res.String())
|
|
}
|
|
return nil
|
|
}
|