Skip to content

Commit

Permalink
Add unlimited method to fetch all records from ES
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Kintsel committed May 27, 2016
1 parent 7420757 commit b3c79a6
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 12 deletions.
23 changes: 16 additions & 7 deletions lib/chewy/query.rb
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ def timeout value
# size: 100
# }}
#
def limit value
chain { criteria.update_request_options size: Integer(value) }
def limit value = nil, &block
chain { criteria.update_request_options size: block || Integer(value) }
end

# Sets elasticsearch <tt>from</tt> search request param
Expand All @@ -301,8 +301,8 @@ def limit value
# from: 300
# }}
#
def offset value
chain { criteria.update_request_options from: Integer(value) }
def offset value = nil, &block
chain { criteria.update_request_options from: block || Integer(value) }
end

# Elasticsearch highlight query option support
Expand Down Expand Up @@ -894,8 +894,8 @@ def types! *params
# scope = UsersIndex.aggs(max_age: { max: { field: 'age' } }).search_type(:count)
# max_age = scope.aggs['max_age']['value']
#
def search_type val
chain { options.merge!(search_type: val) }
def search_type value
chain { criteria.update_search_options search_type: value }
end

# Merges two queries.
Expand Down Expand Up @@ -961,6 +961,16 @@ def exists?
search_type(:count).total > 0
end

# Sets limit to be equal to total documents count
#
# PlacesIndex.query(...).filter(...).unlimited
#

def unlimited
count_query = search_type(:count)
offset(0).limit { count_query.total }
end

# Returns request total time elapsed as reported by elasticsearch
#
# UsersIndex.query(...).filter(...).took
Expand Down Expand Up @@ -1004,7 +1014,6 @@ def _request
@_request ||= begin
request = criteria.request_body
request.merge!(index: _indexes.map(&:index_name), type: _types.map(&:type_name))
request.merge!(search_type: options[:search_type]) if options[:search_type]
request
end
end
Expand Down
14 changes: 12 additions & 2 deletions lib/chewy/query/criteria.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Query
class Criteria
include Compose
ARRAY_STORAGES = [:queries, :filters, :post_filters, :sort, :fields, :types, :scores]
HASH_STORAGES = [:options, :request_options, :facets, :aggregations, :suggest, :script_fields]
HASH_STORAGES = [:options, :search_options, :request_options, :facets, :aggregations, :suggest, :script_fields]
STORAGES = ARRAY_STORAGES + HASH_STORAGES

def initialize options = {}
Expand Down Expand Up @@ -48,6 +48,10 @@ def update_request_options(modifier)
request_options.merge!(modifier)
end

def update_search_options(modifier)
search_options.merge!(modifier)
end

def update_facets(modifier)
facets.merge!(modifier)
end
Expand Down Expand Up @@ -120,7 +124,7 @@ def request_body

body = _boost_query(body)

{ body: body.merge!(request_options) }
{ body: body.merge!(_request_options) }.merge!(search_options)
end
end

Expand Down Expand Up @@ -154,6 +158,12 @@ def _boost_query(body)
body.tap { |b| b[:query] = { function_score: score } }
end

def _request_options
Hash[request_options.map do |key, value|
[key, value.is_a?(Proc) ? value.call : value]
end]
end

def _request_query
_queries_join(queries, options[:query_mode])
end
Expand Down
2 changes: 1 addition & 1 deletion lib/chewy/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Search
:boost_factor, :weight, :random_score, :field_value_factor, :decay, :aggregations,
:suggest, :none, :strategy, :query, :filter, :post_filter, :boost_mode,
:score_mode, :order, :reorder, :only, :types, :delete_all, :find, :total,
:total_count, :total_entries, to: :all
:total_count, :total_entries, :unlimited, to: :all
end

module ClassMethods
Expand Down
18 changes: 16 additions & 2 deletions spec/chewy/query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,15 @@
specify { expect(subject.limit(10)).not_to eq(subject) }
specify { expect(subject.limit(10).criteria.request_options).to include(size: 10) }
specify { expect { subject.limit(10) }.not_to change { subject.criteria.request_options } }
specify { expect(subject.limit { 20/2 }.criteria.request_body[:body]).to include(size: 10) }
end

describe '#offset' do
specify { expect(subject.offset(10)).to be_a described_class }
specify { expect(subject.offset(10)).not_to eq(subject) }
specify { expect(subject.offset(10).criteria.request_options).to include(from: 10) }
specify { expect { subject.offset(10) }.not_to change { subject.criteria.request_options } }
specify { expect(subject.offset { 20/2 }.criteria.request_body[:body]).to include(from: 10) }
end

describe '#script_fields' do
Expand Down Expand Up @@ -454,7 +456,7 @@
end

describe '#exists?' do
let(:data) { 10.times.map { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } }
let(:data) { 10.times.map { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next} } }

before { ProductsIndex::Product.import!(data.map { |h| double(h) }) }

Expand All @@ -464,6 +466,18 @@
specify { expect(subject.filter(range: {age: {lt: 0}}).exists?).to eq false }
end

describe '#unlimited' do
let(:data_length) { 10 }
let(:data) { data_length.times.map { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next} } }

before { ProductsIndex::Product.import!(data.map { |h| double(h) }) }

specify { expect(subject.unlimited.count).to eq data_length }
specify { expect(subject.offset(5).unlimited.count).to eq data_length }
specify { expect(subject.limit(1).unlimited.count).to eq data_length }
specify { expect(subject.unlimited.limit(1).count).to eq 1 }
end

describe '#none' do
specify { expect(subject.none).to be_a described_class }
specify { expect(subject.none).not_to eq(subject) }
Expand Down Expand Up @@ -577,7 +591,7 @@
end

describe '#search_type' do
specify { expect(subject.search_type(:count).options).to include(search_type: :count) }
specify { expect(subject.search_type(:count).criteria.search_options).to include(search_type: :count) }
end

describe '#aggregations' do
Expand Down

0 comments on commit b3c79a6

Please sign in to comment.