Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions elasticsearch-model/lib/elasticsearch/model/adapters/multiple.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ module Records
def records
records_by_type = __records_by_type

response.response["hits"]["hits"].map do |hit|
records = response.response["hits"]["hits"].map do |hit|
records_by_type[ __type_for_hit(hit) ][ hit[:_id] ]
end

records.compact
end

# Returns the collection of records grouped by class based on `_type`
Expand Down Expand Up @@ -49,14 +51,13 @@ def __records_by_type
# @api private
#
def __records_for_klass(klass, ids)
adapter = __adapter_name_for_klass(klass)
adapter = __adapter_for_klass(klass)

case adapter
when Elasticsearch::Model::Adapter::ActiveRecord
if Elasticsearch::Model::Adapter::ActiveRecord.equal?(adapter)
klass.where(klass.primary_key => ids)
when Elasticsearch::Model::Adapter::Mongoid
elsif Elasticsearch::Model::Adapter::Mongoid.equal?(adapter)
klass.where(:id.in => ids)
else
else
klass.find(ids)
end
end
Expand Down Expand Up @@ -100,7 +101,7 @@ def __type_for_hit(hit)
#
# @api private
#
def __adapter_name_for_klass(klass)
def __adapter_for_klass(klass)
Adapter.adapters.select { |name, checker| checker.call(klass) }.keys.first
end
end
Expand Down
61 changes: 35 additions & 26 deletions elasticsearch-model/test/integration/multiple_models_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,28 @@ class MultipleModelsIntegration < Elasticsearch::Test::IntegrationTestCase
end
end

class ::Episode < ActiveRecord::Base
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
module ::NameSearch
extend ActiveSupport::Concern

included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks

settings index: {number_of_shards: 1, number_of_replicas: 0} do
mapping do
indexes :name, type: 'string', analyzer: 'snowball'
indexes :created_at, type: 'date'
settings index: {number_of_shards: 1, number_of_replicas: 0} do
mapping do
indexes :name, type: 'string', analyzer: 'snowball'
indexes :created_at, type: 'date'
end
end
end
end

class ::Series < ActiveRecord::Base
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
class ::Episode < ActiveRecord::Base
include NameSearch
end

settings index: {number_of_shards: 1, number_of_replicas: 0} do
mapping do
indexes :name, type: 'string', analyzer: 'snowball'
indexes :created_at, type: 'date'
end
end
class ::Series < ActiveRecord::Base
include NameSearch
end

[::Episode, ::Series].each do |model|
Expand All @@ -56,7 +56,7 @@ class ::Series < ActiveRecord::Base
end

should "find matching documents across multiple models" do
response = Elasticsearch::Model.search("greatest", [Series, Episode])
response = Elasticsearch::Model.search("\"The greatest Episode\"^2 OR \"The greatest Series\"", [Series, Episode])

assert response.any?, "Response should not be empty: #{response.to_a.inspect}"

Expand All @@ -75,22 +75,31 @@ class ::Series < ActiveRecord::Base
end

should "provide access to results" do
q = {query: {query_string: {query: 'A great *'}}, highlight: {fields: {name: {}}}}
response = Elasticsearch::Model.search(q, [Series, Episode])
response = Elasticsearch::Model.search("\"A great Episode\"^2 OR \"A great Series\"", [Series, Episode])

assert_equal 'A great Episode', response.results[0].name
assert_equal true, response.results[0].name?
assert_equal false, response.results[0].boo?
assert_equal true, response.results[0].highlight?
assert_equal true, response.results[0].highlight.name?
assert_equal false, response.results[0].highlight.boo?

assert_equal 'A great Series', response.results[1].name
assert_equal true, response.results[1].name?
assert_equal false, response.results[1].boo?
assert_equal true, response.results[1].highlight?
assert_equal true, response.results[1].highlight.name?
assert_equal false, response.results[1].highlight.boo?
end

should "only retrieve records for existing results" do
::Series.find_by_name("The greatest Series").delete
response = Elasticsearch::Model.search("\"The greatest Episode\"^2 OR \"The greatest Series\"", [Series, Episode])

assert response.any?, "Response should not be empty: #{response.to_a.inspect}"

assert_equal 2, response.results.size
assert_equal 1, response.records.size

assert_instance_of Elasticsearch::Model::Response::Result, response.results.first
assert_instance_of Episode, response.records.first

assert_equal 'The greatest Episode', response.results[0].name
assert_equal 'The greatest Episode', response.records[0].name
end

if Mongo.available?
Expand Down Expand Up @@ -128,7 +137,7 @@ def as_indexed_json(options={})
end

should "find matching documents across multiple models" do
response = Elasticsearch::Model.search("greatest", [Episode, Image])
response = Elasticsearch::Model.search("\"greatest Episode\" OR \"greatest Image\"^2", [Episode, Image])

assert response.any?, "Response should not be empty: #{response.to_a.inspect}"

Expand Down
4 changes: 3 additions & 1 deletion elasticsearch-model/test/unit/adapter_mongoid_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ def ids

context "Importing" do
should "implement the __find_in_batches method" do
DummyClassForMongoid.expects(:all).returns([])
relation = mock()
relation.stubs(:no_timeout).returns([])
DummyClassForMongoid.expects(:all).returns(relation)

DummyClassForMongoid.__send__ :extend, Elasticsearch::Model::Adapter::Mongoid::Importing
DummyClassForMongoid.__find_in_batches do; end
Expand Down