github.com/weaviate/weaviate@v1.24.6/usecases/objects/batch_delete.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package objects 13 14 import ( 15 "context" 16 "errors" 17 "fmt" 18 19 "github.com/weaviate/weaviate/adapters/handlers/rest/filterext" 20 "github.com/weaviate/weaviate/entities/additional" 21 "github.com/weaviate/weaviate/entities/filters" 22 "github.com/weaviate/weaviate/entities/models" 23 "github.com/weaviate/weaviate/entities/schema" 24 "github.com/weaviate/weaviate/entities/verbosity" 25 ) 26 27 // DeleteObjects deletes objects in batch based on the match filter 28 func (b *BatchManager) DeleteObjects(ctx context.Context, principal *models.Principal, 29 match *models.BatchDeleteMatch, dryRun *bool, output *string, 30 repl *additional.ReplicationProperties, tenant string, 31 ) (*BatchDeleteResponse, error) { 32 err := b.authorizer.Authorize(principal, "delete", "batch/objects") 33 if err != nil { 34 return nil, err 35 } 36 37 unlock, err := b.locks.LockConnector() 38 if err != nil { 39 return nil, NewErrInternal("could not acquire lock: %v", err) 40 } 41 defer unlock() 42 43 b.metrics.BatchDeleteInc() 44 defer b.metrics.BatchDeleteDec() 45 46 return b.deleteObjects(ctx, principal, match, dryRun, output, repl, tenant) 47 } 48 49 // DeleteObjectsFromGRPC deletes objects in batch based on the match filter 50 func (b *BatchManager) DeleteObjectsFromGRPC(ctx context.Context, principal *models.Principal, 51 params BatchDeleteParams, 52 repl *additional.ReplicationProperties, tenant string, 53 ) (BatchDeleteResult, error) { 54 err := b.authorizer.Authorize(principal, "delete", "batch/objects") 55 if err != nil { 56 return BatchDeleteResult{}, err 57 } 58 59 unlock, err := b.locks.LockConnector() 60 if err != nil { 61 return BatchDeleteResult{}, NewErrInternal("could not acquire lock: %v", err) 62 } 63 defer unlock() 64 65 b.metrics.BatchDeleteInc() 66 defer b.metrics.BatchDeleteDec() 67 68 return b.vectorRepo.BatchDeleteObjects(ctx, params, repl, tenant) 69 } 70 71 func (b *BatchManager) deleteObjects(ctx context.Context, principal *models.Principal, 72 match *models.BatchDeleteMatch, dryRun *bool, output *string, 73 repl *additional.ReplicationProperties, tenant string, 74 ) (*BatchDeleteResponse, error) { 75 params, err := b.validateBatchDelete(ctx, principal, match, dryRun, output) 76 if err != nil { 77 return nil, NewErrInvalidUserInput("validate: %v", err) 78 } 79 80 result, err := b.vectorRepo.BatchDeleteObjects(ctx, *params, repl, tenant) 81 if err != nil { 82 return nil, fmt.Errorf("batch delete objects: %w", err) 83 } 84 85 return b.toResponse(match, params.Output, result) 86 } 87 88 func (b *BatchManager) toResponse(match *models.BatchDeleteMatch, output string, 89 result BatchDeleteResult, 90 ) (*BatchDeleteResponse, error) { 91 response := &BatchDeleteResponse{ 92 Match: match, 93 Output: output, 94 DryRun: result.DryRun, 95 Result: BatchDeleteResult{ 96 Matches: result.Matches, 97 Limit: result.Limit, 98 Objects: result.Objects, 99 }, 100 } 101 return response, nil 102 } 103 104 func (b *BatchManager) validateBatchDelete(ctx context.Context, principal *models.Principal, 105 match *models.BatchDeleteMatch, dryRun *bool, output *string, 106 ) (*BatchDeleteParams, error) { 107 if match == nil { 108 return nil, errors.New("empty match clause") 109 } 110 111 if len(match.Class) == 0 { 112 return nil, errors.New("empty match.class clause") 113 } 114 115 if match.Where == nil { 116 return nil, errors.New("empty match.where clause") 117 } 118 119 // Validate schema given in body with the weaviate schema 120 s, err := b.schemaManager.GetSchema(principal) 121 if err != nil { 122 return nil, fmt.Errorf("failed to get schema: %s", err) 123 } 124 125 class := s.FindClassByName(schema.ClassName(match.Class)) 126 if class == nil { 127 return nil, fmt.Errorf("class: %v doesn't exist", match.Class) 128 } 129 130 filter, err := filterext.Parse(match.Where, class.Class) 131 if err != nil { 132 return nil, fmt.Errorf("failed to parse where filter: %s", err) 133 } 134 135 err = filters.ValidateFilters(s, filter) 136 if err != nil { 137 return nil, fmt.Errorf("invalid where filter: %s", err) 138 } 139 140 dryRunParam := false 141 if dryRun != nil { 142 dryRunParam = *dryRun 143 } 144 145 outputParam, err := verbosity.ParseOutput(output) 146 if err != nil { 147 return nil, err 148 } 149 150 params := &BatchDeleteParams{ 151 ClassName: schema.ClassName(class.Class), 152 Filters: filter, 153 DryRun: dryRunParam, 154 Output: outputParam, 155 } 156 return params, nil 157 }