- 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
69 lines
1.6 KiB
Go
69 lines
1.6 KiB
Go
package elasticsearch
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/elastic/go-elasticsearch/v8/esapi"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// EnsureIndices creates indices if they don't exist (F361, F362)
|
|
func (c *Client) EnsureIndices(ctx context.Context) error {
|
|
if c == nil {
|
|
return nil
|
|
}
|
|
indices := []struct {
|
|
name string
|
|
mapping string
|
|
}{
|
|
{indexName(c.Config.Index, IdxTracks), tracksMapping},
|
|
{indexName(c.Config.Index, IdxUsers), usersMapping},
|
|
{indexName(c.Config.Index, IdxPlaylists), playlistsMapping},
|
|
}
|
|
for _, idx := range indices {
|
|
exists, err := c.Indices.Exists([]string{idx.name}, c.Indices.Exists.WithContext(ctx))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if exists.StatusCode == 200 {
|
|
if c.Logger != nil {
|
|
c.Logger.Debug("Elasticsearch index exists", zap.String("index", idx.name))
|
|
}
|
|
continue
|
|
}
|
|
res, err := c.Indices.Create(
|
|
idx.name,
|
|
c.Indices.Create.WithContext(ctx),
|
|
c.Indices.Create.WithBody(strings.NewReader(idx.mapping)),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer res.Body.Close()
|
|
if res.IsError() {
|
|
return fmtErr(res)
|
|
}
|
|
if c.Logger != nil {
|
|
c.Logger.Info("Elasticsearch index created", zap.String("index", idx.name))
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func indexName(prefix, name string) string {
|
|
if prefix != "" {
|
|
return prefix + "-" + name
|
|
}
|
|
return "veza-" + name
|
|
}
|
|
|
|
func fmtErr(res *esapi.Response) error {
|
|
var buf bytes.Buffer
|
|
if _, err := buf.ReadFrom(res.Body); err == nil {
|
|
return fmt.Errorf("elasticsearch error: %s", buf.String())
|
|
}
|
|
return fmt.Errorf("elasticsearch error: status %d", res.StatusCode)
|
|
}
|