forked from pgaskin/BookBrowser
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmeili.go
135 lines (113 loc) · 2.92 KB
/
meili.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
import (
"fmt"
"log/slog"
"slices"
"time"
"github.com/meilisearch/meilisearch-go"
)
type meiliDB struct {
db *meilisearch.Client
index *meilisearch.Index
}
var stopWords = []string{"de", "het", "een", "the", "a", "an", "of", "and", "or", "in", "to", "for", "on", "at", "by"}
func NewMeiliSearch(host, key, indexName string) (*meiliDB, error) {
slog.Info("Creating meili search client", "host", host)
client := meilisearch.NewClient(meilisearch.ClientConfig{
Host: host,
//APIKey: key,
})
slog.Info("Creating meili search index", "index", indexName)
index := client.Index(indexName)
state, err := client.CreateIndex(&meilisearch.IndexConfig{
Uid: indexName,
PrimaryKey: "Hash",
})
if err != nil {
slog.Warn("Failed to create index", "err", err)
return nil, err
}
for {
slog.Info("Waiting for index to be created")
t, err := client.GetTask(state.TaskUID)
if err != nil {
return nil, fmt.Errorf("unable to retrieve meili task status: %w", err)
}
if t.Status == meilisearch.TaskStatusSucceeded || t.Status == meilisearch.TaskStatusFailed {
break
}
slog.Info("Index not ready yet", "status", t.Status)
time.Sleep(10 * time.Millisecond)
}
cur, err := index.GetStopWords()
if err != nil {
slog.Warn("Failed to get stopWords", "err", err)
return nil, err
}
slices.Sort(stopWords)
if slices.Equal(*cur, stopWords) {
slog.Info("StopWords are already set")
} else {
slog.Info("updating stopWords in database", "current", cur, "new", stopWords)
_, err = index.UpdateStopWords(&stopWords)
if err != nil {
slog.Warn("Failed to update stopWords", "err", err)
return nil, err
}
}
return &meiliDB{
db: client,
index: index,
}, nil
}
func (db *meiliDB) GetBookCount() int {
stats, err := db.index.GetStats()
if err != nil {
return 0
}
return int(stats.NumberOfDocuments)
}
func (db *meiliDB) HasHash(h string) (bool, error) {
var doc Book
err := db.index.GetDocument(h, nil, &doc)
if doc.Hash == h {
return true, nil
}
return false, err
}
func (db *meiliDB) GetBook(h string) (*Book, error) {
var b Book
err := db.index.GetDocument(h, nil, &b)
return &b, err
}
func (db *meiliDB) AddBooks(books []Book) error {
//TODO: do something with task info or ignore?
_, err := db.index.AddDocuments(books)
return err
}
func (db *meiliDB) DeleteBook(hash string) error {
//TODO: do something with task info or ignore?
_, err := db.index.DeleteDocument(hash)
return err
}
func (db *meiliDB) GetBooks(q string, limit, offset int64) (*SearchResult, error) {
var books []Book
resp, err := db.index.Search(q, &meilisearch.SearchRequest{
Limit: limit,
Offset: offset,
})
if err != nil {
return nil, err
}
for _, hit := range resp.Hits {
book, err := parseResult(hit)
if err != nil {
slog.Warn("Failed to decode book", "err", err)
}
books = append(books, *book)
}
return &SearchResult{
Items: books,
Total: resp.EstimatedTotalHits,
}, nil
}