5
5
"errors"
6
6
"math"
7
7
"path"
8
- "path/filepath"
9
8
"reflect"
10
9
"strings"
11
10
"time"
@@ -31,44 +30,44 @@ import (
31
30
searchMessage "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/search/v0"
32
31
searchService "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/search/v0"
33
32
"github.com/owncloud/ocis/v2/services/search/pkg/content"
33
+ bleveEngine "github.com/owncloud/ocis/v2/services/search/pkg/engine/bleve"
34
34
searchQuery "github.com/owncloud/ocis/v2/services/search/pkg/query"
35
35
)
36
36
37
37
// Bleve represents a search engine which utilizes bleve to search and store resources.
38
38
type Bleve struct {
39
- index bleve. Index
39
+ indexGetter bleveEngine. IndexGetter
40
40
queryCreator searchQuery.Creator [query.Query ]
41
41
}
42
42
43
- // NewBleveIndex returns a new bleve index
44
- // given path must exist.
45
- func NewBleveIndex (root string ) (bleve.Index , error ) {
46
- destination := filepath .Join (root , "bleve" )
47
- index , err := bleve .Open (destination )
48
- if errors .Is (bleve .ErrorIndexPathDoesNotExist , err ) {
49
- m , err := BuildBleveMapping ()
50
- if err != nil {
51
- return nil , err
52
- }
53
- index , err = bleve .New (destination , m )
54
- if err != nil {
55
- return nil , err
56
- }
57
-
58
- return index , nil
59
- }
60
-
61
- return index , err
62
- }
63
-
64
43
// NewBleveEngine creates a new Bleve instance
65
- func NewBleveEngine (index bleve.Index , queryCreator searchQuery.Creator [query.Query ]) * Bleve {
44
+ // If scalable is set to true, one connection to the index is created and
45
+ // closed per operation, so multiple operations can be executed in parallel.
46
+ // If set to false, only one write connection is created for the whole
47
+ // service, which will lock the index for other processes. In this case,
48
+ // you must close the engine yourself.
49
+ func NewBleveEngine (indexGetter bleveEngine.IndexGetter , queryCreator searchQuery.Creator [query.Query ]) * Bleve {
66
50
return & Bleve {
67
- index : index ,
51
+ indexGetter : indexGetter ,
68
52
queryCreator : queryCreator ,
69
53
}
70
54
}
71
55
56
+ // Close will get the index and close it. If the indexGetter is returning
57
+ // new instances, this method will close just the new returned instance but
58
+ // not any other instances that might be in use.
59
+ //
60
+ // This method is useful if "memory" and "persistent" (not "persistentScale")
61
+ // index getters are used.
62
+ func (b * Bleve ) Close () error {
63
+ // regardless of the implementation, we want to close the index
64
+ bleveIndex , _ , err := b .indexGetter .GetIndex ()
65
+ if err != nil {
66
+ return err
67
+ }
68
+ return bleveIndex .Close ()
69
+ }
70
+
72
71
// BuildBleveMapping builds a bleve index mapping which can be used for indexing
73
72
func BuildBleveMapping () (mapping.IndexMapping , error ) {
74
73
nameMapping := bleve .NewTextFieldMapping ()
@@ -123,6 +122,12 @@ func BuildBleveMapping() (mapping.IndexMapping, error) {
123
122
// Search executes a search request operation within the index.
124
123
// Returns a SearchIndexResponse object or an error.
125
124
func (b * Bleve ) Search (ctx context.Context , sir * searchService.SearchIndexRequest ) (* searchService.SearchIndexResponse , error ) {
125
+ bleveIndex , closeFn , err := b .indexGetter .GetIndex (bleveEngine .ReadOnly (true ))
126
+ if err != nil {
127
+ return nil , err
128
+ }
129
+ defer closeFn ()
130
+
126
131
createdQuery , err := b .queryCreator .Create (sir .Query )
127
132
if err != nil {
128
133
if searchQuery .IsValidationError (err ) {
@@ -169,7 +174,7 @@ func (b *Bleve) Search(ctx context.Context, sir *searchService.SearchIndexReques
169
174
}
170
175
171
176
bleveReq .Fields = []string {"*" }
172
- res , err := b . index .Search (bleveReq )
177
+ res , err := bleveIndex .Search (bleveReq )
173
178
if err != nil {
174
179
return nil , err
175
180
}
@@ -237,19 +242,31 @@ func (b *Bleve) Search(ctx context.Context, sir *searchService.SearchIndexReques
237
242
238
243
// Upsert indexes or stores Resource data fields.
239
244
func (b * Bleve ) Upsert (id string , r Resource ) error {
240
- return b .index .Index (id , r )
245
+ bleveIndex , closeFn , err := b .indexGetter .GetIndex ()
246
+ if err != nil {
247
+ return err
248
+ }
249
+ defer closeFn ()
250
+
251
+ return bleveIndex .Index (id , r )
241
252
}
242
253
243
254
// Move updates the resource location and all of its necessary fields.
244
255
func (b * Bleve ) Move (id string , parentid string , target string ) error {
245
- r , err := b .getResource (id )
256
+ bleveIndex , closeFn , err := b .indexGetter .GetIndex ()
257
+ if err != nil {
258
+ return err
259
+ }
260
+ defer closeFn ()
261
+
262
+ r , err := b .getResource (bleveIndex , id )
246
263
if err != nil {
247
264
return err
248
265
}
249
266
currentPath := r .Path
250
267
nextPath := utils .MakeRelativePath (target )
251
268
252
- r , err = b .updateEntity (id , func (r * Resource ) {
269
+ r , err = b .updateEntity (bleveIndex , id , func (r * Resource ) {
253
270
r .Path = nextPath
254
271
r .Name = path .Base (nextPath )
255
272
r .ParentID = parentid
@@ -266,13 +283,13 @@ func (b *Bleve) Move(id string, parentid string, target string) error {
266
283
bleveReq := bleve .NewSearchRequest (q )
267
284
bleveReq .Size = math .MaxInt
268
285
bleveReq .Fields = []string {"*" }
269
- res , err := b . index .Search (bleveReq )
286
+ res , err := bleveIndex .Search (bleveReq )
270
287
if err != nil {
271
288
return err
272
289
}
273
290
274
291
for _ , h := range res .Hits {
275
- _ , err := b .updateEntity (h .ID , func (r * Resource ) {
292
+ _ , err := b .updateEntity (bleveIndex , h .ID , func (r * Resource ) {
276
293
r .Path = strings .Replace (r .Path , currentPath , nextPath , 1 )
277
294
})
278
295
if err != nil {
@@ -289,29 +306,53 @@ func (b *Bleve) Move(id string, parentid string, target string) error {
289
306
// instead of removing the resource it just marks it as deleted!
290
307
// can be undone
291
308
func (b * Bleve ) Delete (id string ) error {
292
- return b .setDeleted (id , true )
309
+ bleveIndex , closeFn , err := b .indexGetter .GetIndex ()
310
+ if err != nil {
311
+ return err
312
+ }
313
+ defer closeFn ()
314
+
315
+ return b .setDeleted (bleveIndex , id , true )
293
316
}
294
317
295
318
// Restore is the counterpart to Delete.
296
319
// It restores the resource which makes it available again.
297
320
func (b * Bleve ) Restore (id string ) error {
298
- return b .setDeleted (id , false )
321
+ bleveIndex , closeFn , err := b .indexGetter .GetIndex ()
322
+ if err != nil {
323
+ return err
324
+ }
325
+ defer closeFn ()
326
+
327
+ return b .setDeleted (bleveIndex , id , false )
299
328
}
300
329
301
330
// Purge removes a resource from the index, irreversible operation.
302
331
func (b * Bleve ) Purge (id string ) error {
303
- return b .index .Delete (id )
332
+ bleveIndex , closeFn , err := b .indexGetter .GetIndex ()
333
+ if err != nil {
334
+ return err
335
+ }
336
+ defer closeFn ()
337
+
338
+ return bleveIndex .Delete (id )
304
339
}
305
340
306
341
// DocCount returns the number of resources in the index.
307
342
func (b * Bleve ) DocCount () (uint64 , error ) {
308
- return b .index .DocCount ()
343
+ bleveIndex , closeFn , err := b .indexGetter .GetIndex (bleveEngine .ReadOnly (true ))
344
+ if err != nil {
345
+ return 0 , err
346
+ }
347
+ defer closeFn ()
348
+
349
+ return bleveIndex .DocCount ()
309
350
}
310
351
311
- func (b * Bleve ) getResource (id string ) (* Resource , error ) {
352
+ func (b * Bleve ) getResource (bleveIndex bleve. Index , id string ) (* Resource , error ) {
312
353
req := bleve .NewSearchRequest (bleve .NewDocIDQuery ([]string {id }))
313
354
req .Fields = []string {"*" }
314
- res , err := b . index .Search (req )
355
+ res , err := bleveIndex .Search (req )
315
356
if err != nil {
316
357
return nil , err
317
358
}
@@ -446,19 +487,19 @@ func getPhotoValue[T any](fields map[string]interface{}) *T {
446
487
return nil
447
488
}
448
489
449
- func (b * Bleve ) updateEntity (id string , mutateFunc func (r * Resource )) (* Resource , error ) {
450
- it , err := b .getResource (id )
490
+ func (b * Bleve ) updateEntity (bleveIndex bleve. Index , id string , mutateFunc func (r * Resource )) (* Resource , error ) {
491
+ it , err := b .getResource (bleveIndex , id )
451
492
if err != nil {
452
493
return nil , err
453
494
}
454
495
455
496
mutateFunc (it )
456
497
457
- return it , b . index .Index (it .ID , it )
498
+ return it , bleveIndex .Index (it .ID , it )
458
499
}
459
500
460
- func (b * Bleve ) setDeleted (id string , deleted bool ) error {
461
- it , err := b .updateEntity (id , func (r * Resource ) {
501
+ func (b * Bleve ) setDeleted (bleveIndex bleve. Index , id string , deleted bool ) error {
502
+ it , err := b .updateEntity (bleveIndex , id , func (r * Resource ) {
462
503
r .Deleted = deleted
463
504
})
464
505
if err != nil {
@@ -473,13 +514,13 @@ func (b *Bleve) setDeleted(id string, deleted bool) error {
473
514
bleveReq := bleve .NewSearchRequest (q )
474
515
bleveReq .Size = math .MaxInt
475
516
bleveReq .Fields = []string {"*" }
476
- res , err := b . index .Search (bleveReq )
517
+ res , err := bleveIndex .Search (bleveReq )
477
518
if err != nil {
478
519
return err
479
520
}
480
521
481
522
for _ , h := range res .Hits {
482
- _ , err := b .updateEntity (h .ID , func (r * Resource ) {
523
+ _ , err := b .updateEntity (bleveIndex , h .ID , func (r * Resource ) {
483
524
r .Deleted = deleted
484
525
})
485
526
if err != nil {
0 commit comments