Skip to content

Commit

Permalink
Merge pull request #438 from meilisearch/delete-documents-by-filter
Browse files Browse the repository at this point in the history
Delete documents by filter
  • Loading branch information
brunoocasali committed May 22, 2023
2 parents 90af26e + 307c268 commit 3eb2d12
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 10 deletions.
6 changes: 3 additions & 3 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2023-03-30 12:31:09 UTC using RuboCop version 1.48.1.
# on 2023-05-20 01:53:00 UTC using RuboCop version 1.50.2.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
Expand All @@ -14,7 +14,7 @@ Gemspec/RequireMFA:
Exclude:
- 'meilisearch.gemspec'

# Offense count: 45
# Offense count: 46
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
# AllowedMethods: refine
Metrics/BlockLength:
Expand All @@ -23,7 +23,7 @@ Metrics/BlockLength:
# Offense count: 2
# Configuration parameters: CountComments, CountAsOne.
Metrics/ClassLength:
Max: 318
Max: 321

# Offense count: 1
# Configuration parameters: Max, CountKeywordArgs.
Expand Down
23 changes: 18 additions & 5 deletions lib/meilisearch/index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,24 @@ def update_documents_in_batches!(documents, batch_size = 1000, primary_key = nil
responses
end

def delete_documents(documents_ids)
if documents_ids.is_a?(Array)
http_post "/indexes/#{@uid}/documents/delete-batch", documents_ids
else
delete_document(documents_ids)
# Public: Delete documents from an index
#
# options: A Hash or an Array containing documents_ids or a hash with filter:.
# filter: - A hash containing a filter that should match documents.
# Available ONLY with Meilisearch v1.2 and newer (optional)
#
# Returns a Task object.
def delete_documents(options = {})
Utils.version_error_handler(__method__) do
if options.is_a?(Hash) && options.key?(:filter)
http_post "/indexes/#{@uid}/documents/delete", options
else
# backwards compatibility:
# expect to be a array or/number/string to send alongside as documents_ids.
options = [options] unless options.is_a?(Array)

http_post "/indexes/#{@uid}/documents/delete-batch", options
end
end
end
alias delete_multiple_documents delete_documents
Expand Down
17 changes: 16 additions & 1 deletion lib/meilisearch/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ def self.parse_query(original_options, allowed_params = [])
end
end

private_class_method :parse
def self.message_builder(current_message, method_name)
"#{current_message}\nHint: It might not be working because maybe you're not up " \
"to date with the Meilisearch version that `#{method_name}` call requires."
end

def self.version_error_handler(method_name)
yield if block_given?
rescue MeiliSearch::ApiError => e
message = message_builder(e.http_message, method_name)

raise MeiliSearch::ApiError.new(e.http_code, message, e.http_body)
rescue StandardError => e
raise e.class, message_builder(e.message, method_name)
end

private_class_method :parse, :message_builder
end
end
17 changes: 17 additions & 0 deletions spec/meilisearch/index/documents_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,23 @@
expect { index.document(id) }.to raise_document_not_found_meilisearch_api_error
end

it 'deletes documents based on filter from index (with delete route)' do
expect do
index.update_filterable_attributes(['objectId'])
task = index.delete_documents(filter: ['objectId > 0'])

client.wait_for_task(task['taskUid'])
end.to(change { index.documents['results'].size }.by(-documents.size))
end

it 'ignores filter even when documents_ids is empty (with delete-batch route)' do
expect do
task = index.delete_documents(filter: ['objectId > 0'])

client.wait_for_task(task['taskUid'])
end.to(change { index.documents['results'].size }.by(0))
end

it 'deletes one document synchronously from index (with delete-batch route)' do
id = 2
expect do
Expand Down
2 changes: 1 addition & 1 deletion spec/meilisearch/index/search/multi_params_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
expect(response['hits'].first).not_to have_key('objectId')
expect(response['hits'].first).not_to have_key('genre')
expect(response['hits'].first).to have_key('title')
expect(response['hits'].first['_formatted']['title']).to eq('Harry Potter and the Half-Blood <em>Princ</em>e')
expect(response['hits'].first['_formatted']['title']).to eq('Harry Potter and the Half-Blood <em>Prince</em>')
end

it 'does a custom search with facets and limit' do
Expand Down
26 changes: 26 additions & 0 deletions spec/meilisearch/utils_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,30 @@
)
end
end

describe '.version_error_handler' do
it 'spawns same error message' do
expect do
MeiliSearch::Utils.version_error_handler(:my_method) do
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', {})
end
end.to raise_error(MeiliSearch::ApiError, /I came from Meili server/)
end

it 'spawns message with version hint' do
expect do
MeiliSearch::Utils.version_error_handler(:my_method) do
raise MeiliSearch::ApiError.new(405, 'I came from Meili server', {})
end
end.to raise_error(MeiliSearch::ApiError, /that `my_method` call requires/)
end

it 'adds hints to all error types' do
expect do
MeiliSearch::Utils.version_error_handler(:my_method) do
raise MeiliSearch::CommunicationError, 'I am an error'
end
end.to raise_error(MeiliSearch::CommunicationError, /that `my_method` call requires/)
end
end
end

0 comments on commit 3eb2d12

Please sign in to comment.