Skip to content

Commit 3eb2d12

Browse files
authored
Merge pull request #438 from meilisearch/delete-documents-by-filter
Delete documents by filter
2 parents 90af26e + 307c268 commit 3eb2d12

File tree

6 files changed

+81
-10
lines changed

6 files changed

+81
-10
lines changed

.rubocop_todo.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This configuration was generated by
22
# `rubocop --auto-gen-config`
3-
# on 2023-03-30 12:31:09 UTC using RuboCop version 1.48.1.
3+
# on 2023-05-20 01:53:00 UTC using RuboCop version 1.50.2.
44
# The point is for the user to remove these configuration records
55
# one by one as the offenses are removed from the code base.
66
# Note that changes in the inspected code, or installation of new
@@ -14,7 +14,7 @@ Gemspec/RequireMFA:
1414
Exclude:
1515
- 'meilisearch.gemspec'
1616

17-
# Offense count: 45
17+
# Offense count: 46
1818
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
1919
# AllowedMethods: refine
2020
Metrics/BlockLength:
@@ -23,7 +23,7 @@ Metrics/BlockLength:
2323
# Offense count: 2
2424
# Configuration parameters: CountComments, CountAsOne.
2525
Metrics/ClassLength:
26-
Max: 318
26+
Max: 321
2727

2828
# Offense count: 1
2929
# Configuration parameters: Max, CountKeywordArgs.

lib/meilisearch/index.rb

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,24 @@ def update_documents_in_batches!(documents, batch_size = 1000, primary_key = nil
153153
responses
154154
end
155155

156-
def delete_documents(documents_ids)
157-
if documents_ids.is_a?(Array)
158-
http_post "/indexes/#{@uid}/documents/delete-batch", documents_ids
159-
else
160-
delete_document(documents_ids)
156+
# Public: Delete documents from an index
157+
#
158+
# options: A Hash or an Array containing documents_ids or a hash with filter:.
159+
# filter: - A hash containing a filter that should match documents.
160+
# Available ONLY with Meilisearch v1.2 and newer (optional)
161+
#
162+
# Returns a Task object.
163+
def delete_documents(options = {})
164+
Utils.version_error_handler(__method__) do
165+
if options.is_a?(Hash) && options.key?(:filter)
166+
http_post "/indexes/#{@uid}/documents/delete", options
167+
else
168+
# backwards compatibility:
169+
# expect to be a array or/number/string to send alongside as documents_ids.
170+
options = [options] unless options.is_a?(Array)
171+
172+
http_post "/indexes/#{@uid}/documents/delete-batch", options
173+
end
161174
end
162175
end
163176
alias delete_multiple_documents delete_documents

lib/meilisearch/utils.rb

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,21 @@ def self.parse_query(original_options, allowed_params = [])
3333
end
3434
end
3535

36-
private_class_method :parse
36+
def self.message_builder(current_message, method_name)
37+
"#{current_message}\nHint: It might not be working because maybe you're not up " \
38+
"to date with the Meilisearch version that `#{method_name}` call requires."
39+
end
40+
41+
def self.version_error_handler(method_name)
42+
yield if block_given?
43+
rescue MeiliSearch::ApiError => e
44+
message = message_builder(e.http_message, method_name)
45+
46+
raise MeiliSearch::ApiError.new(e.http_code, message, e.http_body)
47+
rescue StandardError => e
48+
raise e.class, message_builder(e.message, method_name)
49+
end
50+
51+
private_class_method :parse, :message_builder
3752
end
3853
end

spec/meilisearch/index/documents_spec.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,23 @@
390390
expect { index.document(id) }.to raise_document_not_found_meilisearch_api_error
391391
end
392392

393+
it 'deletes documents based on filter from index (with delete route)' do
394+
expect do
395+
index.update_filterable_attributes(['objectId'])
396+
task = index.delete_documents(filter: ['objectId > 0'])
397+
398+
client.wait_for_task(task['taskUid'])
399+
end.to(change { index.documents['results'].size }.by(-documents.size))
400+
end
401+
402+
it 'ignores filter even when documents_ids is empty (with delete-batch route)' do
403+
expect do
404+
task = index.delete_documents(filter: ['objectId > 0'])
405+
406+
client.wait_for_task(task['taskUid'])
407+
end.to(change { index.documents['results'].size }.by(0))
408+
end
409+
393410
it 'deletes one document synchronously from index (with delete-batch route)' do
394411
id = 2
395412
expect do

spec/meilisearch/index/search/multi_params_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
expect(response['hits'].first).not_to have_key('objectId')
6060
expect(response['hits'].first).not_to have_key('genre')
6161
expect(response['hits'].first).to have_key('title')
62-
expect(response['hits'].first['_formatted']['title']).to eq('Harry Potter and the Half-Blood <em>Princ</em>e')
62+
expect(response['hits'].first['_formatted']['title']).to eq('Harry Potter and the Half-Blood <em>Prince</em>')
6363
end
6464

6565
it 'does a custom search with facets and limit' do

spec/meilisearch/utils_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,30 @@
4646
)
4747
end
4848
end
49+
50+
describe '.version_error_handler' do
51+
it 'spawns same error message' do
52+
expect do
53+
MeiliSearch::Utils.version_error_handler(:my_method) do
54+
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', {})
55+
end
56+
end.to raise_error(MeiliSearch::ApiError, /I came from Meili server/)
57+
end
58+
59+
it 'spawns message with version hint' do
60+
expect do
61+
MeiliSearch::Utils.version_error_handler(:my_method) do
62+
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', {})
63+
end
64+
end.to raise_error(MeiliSearch::ApiError, /that `my_method` call requires/)
65+
end
66+
67+
it 'adds hints to all error types' do
68+
expect do
69+
MeiliSearch::Utils.version_error_handler(:my_method) do
70+
raise MeiliSearch::CommunicationError, 'I am an error'
71+
end
72+
end.to raise_error(MeiliSearch::CommunicationError, /that `my_method` call requires/)
73+
end
74+
end
4975
end

0 commit comments

Comments
 (0)