elasticsearch-model 6.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +5 -0
- data/README.md +14 -7
- data/Rakefile +27 -36
- data/elasticsearch-model.gemspec +1 -1
- data/examples/activerecord_mapping_completion.rb +2 -15
- data/gemfiles/3.0.gemfile +6 -1
- data/gemfiles/4.0.gemfile +7 -1
- data/gemfiles/5.0.gemfile +6 -0
- data/lib/elasticsearch/model.rb +15 -8
- data/lib/elasticsearch/model/adapters/active_record.rb +7 -26
- data/lib/elasticsearch/model/indexing.rb +5 -3
- data/lib/elasticsearch/model/naming.rb +6 -1
- data/lib/elasticsearch/model/response.rb +2 -2
- data/lib/elasticsearch/model/response/pagination.rb +2 -192
- data/lib/elasticsearch/model/response/pagination/kaminari.rb +109 -0
- data/lib/elasticsearch/model/response/pagination/will_paginate.rb +95 -0
- data/lib/elasticsearch/model/response/result.rb +1 -1
- data/lib/elasticsearch/model/version.rb +1 -1
- data/spec/elasticsearch/model/adapter_spec.rb +119 -0
- data/spec/elasticsearch/model/adapters/active_record/associations_spec.rb +334 -0
- data/spec/elasticsearch/model/adapters/active_record/basic_spec.rb +340 -0
- data/spec/elasticsearch/model/adapters/active_record/dynamic_index_name_spec.rb +18 -0
- data/spec/elasticsearch/model/adapters/active_record/import_spec.rb +187 -0
- data/spec/elasticsearch/model/adapters/active_record/multi_model_spec.rb +110 -0
- data/spec/elasticsearch/model/adapters/active_record/namespaced_model_spec.rb +38 -0
- data/spec/elasticsearch/model/adapters/active_record/pagination_spec.rb +315 -0
- data/spec/elasticsearch/model/adapters/active_record/parent_child_spec.rb +75 -0
- data/spec/elasticsearch/model/adapters/active_record/serialization_spec.rb +61 -0
- data/spec/elasticsearch/model/adapters/active_record_spec.rb +207 -0
- data/spec/elasticsearch/model/adapters/default_spec.rb +41 -0
- data/spec/elasticsearch/model/adapters/mongoid/basic_spec.rb +267 -0
- data/spec/elasticsearch/model/adapters/mongoid/multi_model_spec.rb +66 -0
- data/spec/elasticsearch/model/adapters/mongoid_spec.rb +235 -0
- data/spec/elasticsearch/model/adapters/multiple_spec.rb +125 -0
- data/spec/elasticsearch/model/callbacks_spec.rb +33 -0
- data/spec/elasticsearch/model/client_spec.rb +66 -0
- data/spec/elasticsearch/model/hash_wrapper_spec.rb +12 -0
- data/spec/elasticsearch/model/importing_spec.rb +214 -0
- data/spec/elasticsearch/model/indexing_spec.rb +918 -0
- data/spec/elasticsearch/model/module_spec.rb +101 -0
- data/spec/elasticsearch/model/multimodel_spec.rb +55 -0
- data/spec/elasticsearch/model/naming_inheritance_spec.rb +184 -0
- data/spec/elasticsearch/model/naming_spec.rb +186 -0
- data/spec/elasticsearch/model/proxy_spec.rb +107 -0
- data/spec/elasticsearch/model/response/aggregations_spec.rb +66 -0
- data/spec/elasticsearch/model/response/base_spec.rb +90 -0
- data/spec/elasticsearch/model/response/pagination/kaminari_spec.rb +410 -0
- data/spec/elasticsearch/model/response/pagination/will_paginate_spec.rb +262 -0
- data/spec/elasticsearch/model/response/records_spec.rb +118 -0
- data/spec/elasticsearch/model/response/response_spec.rb +131 -0
- data/spec/elasticsearch/model/response/result_spec.rb +122 -0
- data/spec/elasticsearch/model/response/results_spec.rb +56 -0
- data/spec/elasticsearch/model/searching_search_request_spec.rb +112 -0
- data/spec/elasticsearch/model/searching_spec.rb +49 -0
- data/spec/elasticsearch/model/serializing_spec.rb +22 -0
- data/spec/spec_helper.rb +161 -0
- data/spec/support/app.rb +21 -0
- data/spec/support/app/answer.rb +33 -0
- data/spec/support/app/article.rb +22 -0
- data/spec/support/app/article_for_pagination.rb +12 -0
- data/spec/support/app/article_with_custom_serialization.rb +13 -0
- data/spec/support/app/article_with_dynamic_index_name.rb +15 -0
- data/spec/support/app/author.rb +9 -0
- data/spec/support/app/authorship.rb +4 -0
- data/spec/support/app/category.rb +3 -0
- data/spec/support/app/comment.rb +3 -0
- data/spec/support/app/episode.rb +11 -0
- data/spec/support/app/image.rb +19 -0
- data/spec/support/app/import_article.rb +12 -0
- data/spec/support/app/mongoid_article.rb +21 -0
- data/spec/support/app/namespaced_book.rb +10 -0
- data/spec/support/app/parent_and_child_searchable.rb +24 -0
- data/spec/support/app/post.rb +14 -0
- data/spec/support/app/question.rb +27 -0
- data/spec/support/app/searchable.rb +48 -0
- data/spec/support/app/series.rb +11 -0
- data/spec/support/model.json +1 -0
- data/{test → spec}/support/model.yml +0 -0
- metadata +129 -86
- data/test/integration/active_record_associations_parent_child_test.rb +0 -188
- data/test/integration/active_record_associations_test.rb +0 -339
- data/test/integration/active_record_basic_test.rb +0 -255
- data/test/integration/active_record_custom_serialization_test.rb +0 -67
- data/test/integration/active_record_import_test.rb +0 -168
- data/test/integration/active_record_namespaced_model_test.rb +0 -56
- data/test/integration/active_record_pagination_test.rb +0 -149
- data/test/integration/dynamic_index_name_test.rb +0 -52
- data/test/integration/mongoid_basic_test.rb +0 -240
- data/test/integration/multiple_models_test.rb +0 -176
- data/test/support/model.json +0 -1
- data/test/test_helper.rb +0 -92
- data/test/unit/adapter_active_record_test.rb +0 -157
- data/test/unit/adapter_default_test.rb +0 -41
- data/test/unit/adapter_mongoid_test.rb +0 -161
- data/test/unit/adapter_multiple_test.rb +0 -106
- data/test/unit/adapter_test.rb +0 -69
- data/test/unit/callbacks_test.rb +0 -31
- data/test/unit/client_test.rb +0 -27
- data/test/unit/hash_wrapper_test.rb +0 -13
- data/test/unit/importing_test.rb +0 -224
- data/test/unit/indexing_test.rb +0 -720
- data/test/unit/module_test.rb +0 -68
- data/test/unit/multimodel_test.rb +0 -38
- data/test/unit/naming_inheritance_test.rb +0 -94
- data/test/unit/naming_test.rb +0 -103
- data/test/unit/proxy_test.rb +0 -98
- data/test/unit/response_aggregations_test.rb +0 -46
- data/test/unit/response_base_test.rb +0 -40
- data/test/unit/response_pagination_kaminari_test.rb +0 -433
- data/test/unit/response_pagination_will_paginate_test.rb +0 -398
- data/test/unit/response_records_test.rb +0 -91
- data/test/unit/response_result_test.rb +0 -90
- data/test/unit/response_results_test.rb +0 -34
- data/test/unit/response_test.rb +0 -104
- data/test/unit/searching_search_request_test.rb +0 -78
- data/test/unit/searching_test.rb +0 -41
- data/test/unit/serializing_test.rb +0 -17
@@ -1,188 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'active_record'
|
3
|
-
|
4
|
-
# Needed for ActiveRecord 3.x ?
|
5
|
-
ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => ":memory:" ) unless ActiveRecord::Base.connected?
|
6
|
-
|
7
|
-
::ActiveRecord::Base.raise_in_transactional_callbacks = true if ::ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks) && ::ActiveRecord::VERSION::MAJOR.to_s < '5'
|
8
|
-
|
9
|
-
class Question < ActiveRecord::Base
|
10
|
-
include Elasticsearch::Model
|
11
|
-
|
12
|
-
has_many :answers, dependent: :destroy
|
13
|
-
|
14
|
-
JOIN_TYPE = 'question'.freeze
|
15
|
-
JOIN_METADATA = { join_field: JOIN_TYPE}.freeze
|
16
|
-
|
17
|
-
index_name 'questions_and_answers'.freeze
|
18
|
-
document_type 'doc'.freeze
|
19
|
-
|
20
|
-
mapping do
|
21
|
-
indexes :title
|
22
|
-
indexes :text
|
23
|
-
indexes :author
|
24
|
-
end
|
25
|
-
|
26
|
-
def as_indexed_json(options={})
|
27
|
-
# This line is necessary for differences between ActiveModel::Serializers::JSON#as_json versions
|
28
|
-
json = as_json(options)[JOIN_TYPE] || as_json(options)
|
29
|
-
json.merge(JOIN_METADATA)
|
30
|
-
end
|
31
|
-
|
32
|
-
after_commit lambda { __elasticsearch__.index_document }, on: :create
|
33
|
-
after_commit lambda { __elasticsearch__.update_document }, on: :update
|
34
|
-
after_commit lambda { __elasticsearch__.delete_document }, on: :destroy
|
35
|
-
end
|
36
|
-
|
37
|
-
class Answer < ActiveRecord::Base
|
38
|
-
include Elasticsearch::Model
|
39
|
-
|
40
|
-
belongs_to :question
|
41
|
-
|
42
|
-
JOIN_TYPE = 'answer'.freeze
|
43
|
-
|
44
|
-
index_name 'questions_and_answers'.freeze
|
45
|
-
document_type 'doc'.freeze
|
46
|
-
|
47
|
-
before_create :randomize_id
|
48
|
-
|
49
|
-
def randomize_id
|
50
|
-
begin
|
51
|
-
self.id = SecureRandom.random_number(1_000_000)
|
52
|
-
end while Answer.where(id: self.id).exists?
|
53
|
-
end
|
54
|
-
|
55
|
-
mapping do
|
56
|
-
indexes :text
|
57
|
-
indexes :author
|
58
|
-
end
|
59
|
-
|
60
|
-
def as_indexed_json(options={})
|
61
|
-
# This line is necessary for differences between ActiveModel::Serializers::JSON#as_json versions
|
62
|
-
json = as_json(options)[JOIN_TYPE] || as_json(options)
|
63
|
-
json.merge(join_field: { name: JOIN_TYPE, parent: question_id })
|
64
|
-
end
|
65
|
-
|
66
|
-
after_commit lambda { __elasticsearch__.index_document(routing: (question_id || 1)) }, on: :create
|
67
|
-
after_commit lambda { __elasticsearch__.update_document(routing: (question_id || 1)) }, on: :update
|
68
|
-
after_commit lambda {__elasticsearch__.delete_document(routing: (question_id || 1)) }, on: :destroy
|
69
|
-
end
|
70
|
-
|
71
|
-
module ParentChildSearchable
|
72
|
-
INDEX_NAME = 'questions_and_answers'.freeze
|
73
|
-
JOIN = 'join'.freeze
|
74
|
-
|
75
|
-
def create_index!(options={})
|
76
|
-
client = Question.__elasticsearch__.client
|
77
|
-
client.indices.delete index: INDEX_NAME rescue nil if options[:force]
|
78
|
-
|
79
|
-
settings = Question.settings.to_hash.merge Answer.settings.to_hash
|
80
|
-
mapping_properties = { join_field: { type: JOIN,
|
81
|
-
relations: { Question::JOIN_TYPE => Answer::JOIN_TYPE } } }
|
82
|
-
|
83
|
-
merged_properties = mapping_properties.merge(Question.mappings.to_hash[:doc][:properties]).merge(
|
84
|
-
Answer.mappings.to_hash[:doc][:properties])
|
85
|
-
mappings = { doc: { properties: merged_properties }}
|
86
|
-
|
87
|
-
client.indices.create index: INDEX_NAME,
|
88
|
-
body: {
|
89
|
-
settings: settings.to_hash,
|
90
|
-
mappings: mappings }
|
91
|
-
end
|
92
|
-
|
93
|
-
extend self
|
94
|
-
end
|
95
|
-
|
96
|
-
module Elasticsearch
|
97
|
-
module Model
|
98
|
-
class ActiveRecordAssociationsParentChildIntegrationTest < Elasticsearch::Test::IntegrationTestCase
|
99
|
-
|
100
|
-
context "ActiveRecord associations with parent/child modelling" do
|
101
|
-
setup do
|
102
|
-
ActiveRecord::Schema.define(version: 1) do
|
103
|
-
create_table :questions do |t|
|
104
|
-
t.string :title
|
105
|
-
t.text :text
|
106
|
-
t.string :author
|
107
|
-
t.timestamps null: false
|
108
|
-
end
|
109
|
-
|
110
|
-
create_table :answers do |t|
|
111
|
-
t.text :text
|
112
|
-
t.string :author
|
113
|
-
t.references :question
|
114
|
-
t.timestamps null: false
|
115
|
-
end
|
116
|
-
|
117
|
-
add_index(:answers, :question_id) unless index_exists?(:answers, :question_id)
|
118
|
-
end
|
119
|
-
|
120
|
-
Question.delete_all
|
121
|
-
ParentChildSearchable.create_index! force: true
|
122
|
-
|
123
|
-
q_1 = Question.create! title: 'First Question', author: 'John'
|
124
|
-
q_2 = Question.create! title: 'Second Question', author: 'Jody'
|
125
|
-
|
126
|
-
q_1.answers.create! text: 'Lorem Ipsum', author: 'Adam'
|
127
|
-
q_1.answers.create! text: 'Dolor Sit', author: 'Ryan'
|
128
|
-
|
129
|
-
q_2.answers.create! text: 'Amet Et', author: 'John'
|
130
|
-
|
131
|
-
Question.__elasticsearch__.refresh_index!
|
132
|
-
end
|
133
|
-
|
134
|
-
should "find questions by matching answers" do
|
135
|
-
response = Question.search(
|
136
|
-
{ query: {
|
137
|
-
has_child: {
|
138
|
-
type: 'answer',
|
139
|
-
query: {
|
140
|
-
match: {
|
141
|
-
author: 'john'
|
142
|
-
}
|
143
|
-
}
|
144
|
-
}
|
145
|
-
}
|
146
|
-
})
|
147
|
-
|
148
|
-
assert_equal 'Second Question', response.records.first.title
|
149
|
-
end
|
150
|
-
|
151
|
-
should "find answers for matching questions" do
|
152
|
-
response = Answer.search(
|
153
|
-
{ query: {
|
154
|
-
has_parent: {
|
155
|
-
parent_type: 'question',
|
156
|
-
query: {
|
157
|
-
match: {
|
158
|
-
author: 'john'
|
159
|
-
}
|
160
|
-
}
|
161
|
-
}
|
162
|
-
}
|
163
|
-
})
|
164
|
-
|
165
|
-
assert_same_elements ['Adam', 'Ryan'], response.records.map(&:author)
|
166
|
-
end
|
167
|
-
|
168
|
-
should "delete answers when the question is deleted" do
|
169
|
-
Question.where(title: 'First Question').each(&:destroy)
|
170
|
-
Question.__elasticsearch__.refresh_index!
|
171
|
-
|
172
|
-
response = Answer.search(
|
173
|
-
{ query: {
|
174
|
-
has_parent: {
|
175
|
-
parent_type: 'question',
|
176
|
-
query: {
|
177
|
-
match_all: {}
|
178
|
-
}
|
179
|
-
}
|
180
|
-
}
|
181
|
-
})
|
182
|
-
|
183
|
-
assert_equal 1, response.results.total
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
@@ -1,339 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'active_record'
|
3
|
-
|
4
|
-
# Needed for ActiveRecord 3.x ?
|
5
|
-
ActiveRecord::Base.establish_connection( :adapter => 'sqlite3', :database => ":memory:" ) unless ActiveRecord::Base.connected?
|
6
|
-
|
7
|
-
::ActiveRecord::Base.raise_in_transactional_callbacks = true if ::ActiveRecord::Base.respond_to?(:raise_in_transactional_callbacks) && ::ActiveRecord::VERSION::MAJOR.to_s < '5'
|
8
|
-
|
9
|
-
module Elasticsearch
|
10
|
-
module Model
|
11
|
-
class ActiveRecordAssociationsIntegrationTest < Elasticsearch::Test::IntegrationTestCase
|
12
|
-
|
13
|
-
# ----- Search integration via Concern module -----------------------------------------------------
|
14
|
-
|
15
|
-
module Searchable
|
16
|
-
extend ActiveSupport::Concern
|
17
|
-
|
18
|
-
included do
|
19
|
-
include Elasticsearch::Model
|
20
|
-
include Elasticsearch::Model::Callbacks
|
21
|
-
|
22
|
-
# Set up the mapping
|
23
|
-
#
|
24
|
-
settings index: { number_of_shards: 1, number_of_replicas: 0 } do
|
25
|
-
mapping do
|
26
|
-
indexes :title, analyzer: 'snowball'
|
27
|
-
indexes :created_at, type: 'date'
|
28
|
-
|
29
|
-
indexes :authors do
|
30
|
-
indexes :first_name
|
31
|
-
indexes :last_name
|
32
|
-
indexes :full_name, type: 'text' do
|
33
|
-
indexes :raw, type: 'keyword'
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
indexes :categories, type: 'keyword'
|
38
|
-
|
39
|
-
indexes :comments, type: 'nested' do
|
40
|
-
indexes :text
|
41
|
-
indexes :author
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Customize the JSON serialization for Elasticsearch
|
47
|
-
#
|
48
|
-
def as_indexed_json(options={})
|
49
|
-
{
|
50
|
-
title: title,
|
51
|
-
text: text,
|
52
|
-
categories: categories.map(&:title),
|
53
|
-
authors: authors.as_json(methods: [:full_name], only: [:full_name, :first_name, :last_name]),
|
54
|
-
comments: comments.as_json(only: [:text, :author])
|
55
|
-
}
|
56
|
-
end
|
57
|
-
|
58
|
-
# Update document in the index after touch
|
59
|
-
#
|
60
|
-
after_touch() { __elasticsearch__.index_document }
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
context "ActiveRecord associations" do
|
65
|
-
setup do
|
66
|
-
|
67
|
-
# ----- Schema definition ---------------------------------------------------------------
|
68
|
-
|
69
|
-
ActiveRecord::Schema.define(version: 1) do
|
70
|
-
create_table :categories do |t|
|
71
|
-
t.string :title
|
72
|
-
t.timestamps null: false
|
73
|
-
end
|
74
|
-
|
75
|
-
create_table :categories_posts, id: false do |t|
|
76
|
-
t.references :post, :category
|
77
|
-
end
|
78
|
-
|
79
|
-
create_table :authors do |t|
|
80
|
-
t.string :first_name, :last_name
|
81
|
-
t.timestamps null: false
|
82
|
-
end
|
83
|
-
|
84
|
-
create_table :authorships do |t|
|
85
|
-
t.string :first_name, :last_name
|
86
|
-
t.references :post
|
87
|
-
t.references :author
|
88
|
-
t.timestamps null: false
|
89
|
-
end
|
90
|
-
|
91
|
-
create_table :comments do |t|
|
92
|
-
t.string :text
|
93
|
-
t.string :author
|
94
|
-
t.references :post
|
95
|
-
t.timestamps null: false
|
96
|
-
end
|
97
|
-
|
98
|
-
add_index(:comments, :post_id) unless index_exists?(:comments, :post_id)
|
99
|
-
|
100
|
-
create_table :posts do |t|
|
101
|
-
t.string :title
|
102
|
-
t.text :text
|
103
|
-
t.boolean :published
|
104
|
-
t.timestamps null: false
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
# ----- Models definition -------------------------------------------------------------------------
|
109
|
-
|
110
|
-
class Category < ActiveRecord::Base
|
111
|
-
has_and_belongs_to_many :posts
|
112
|
-
end
|
113
|
-
|
114
|
-
class Author < ActiveRecord::Base
|
115
|
-
has_many :authorships
|
116
|
-
|
117
|
-
after_update { self.authorships.each(&:touch) }
|
118
|
-
|
119
|
-
def full_name
|
120
|
-
[first_name, last_name].compact.join(' ')
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
class Authorship < ActiveRecord::Base
|
125
|
-
belongs_to :author
|
126
|
-
belongs_to :post, touch: true
|
127
|
-
end
|
128
|
-
|
129
|
-
class Comment < ActiveRecord::Base
|
130
|
-
belongs_to :post, touch: true
|
131
|
-
end
|
132
|
-
|
133
|
-
class Post < ActiveRecord::Base
|
134
|
-
has_and_belongs_to_many :categories, after_add: [ lambda { |a,c| a.__elasticsearch__.index_document } ],
|
135
|
-
after_remove: [ lambda { |a,c| a.__elasticsearch__.index_document } ]
|
136
|
-
has_many :authorships
|
137
|
-
has_many :authors, through: :authorships,
|
138
|
-
after_add: [ lambda { |a,c| a.__elasticsearch__.index_document } ],
|
139
|
-
after_remove: [ lambda { |a,c| a.__elasticsearch__.index_document } ]
|
140
|
-
has_many :comments, after_add: [ lambda { |a,c| a.__elasticsearch__.index_document } ],
|
141
|
-
after_remove: [ lambda { |a,c| a.__elasticsearch__.index_document } ]
|
142
|
-
|
143
|
-
after_touch() { __elasticsearch__.index_document }
|
144
|
-
end
|
145
|
-
|
146
|
-
# Include the search integration
|
147
|
-
#
|
148
|
-
Post.__send__ :include, Searchable
|
149
|
-
Comment.__send__ :include, Elasticsearch::Model
|
150
|
-
Comment.__send__ :include, Elasticsearch::Model::Callbacks
|
151
|
-
|
152
|
-
# ----- Reset the indices -----------------------------------------------------------------
|
153
|
-
|
154
|
-
Post.delete_all
|
155
|
-
Post.__elasticsearch__.create_index! force: true
|
156
|
-
|
157
|
-
Comment.delete_all
|
158
|
-
Comment.__elasticsearch__.create_index! force: true
|
159
|
-
end
|
160
|
-
|
161
|
-
should "index and find a document" do
|
162
|
-
Post.create! title: 'Test'
|
163
|
-
Post.create! title: 'Testing Coding'
|
164
|
-
Post.create! title: 'Coding'
|
165
|
-
Post.__elasticsearch__.refresh_index!
|
166
|
-
|
167
|
-
response = Post.search('title:test')
|
168
|
-
|
169
|
-
assert_equal 2, response.results.size
|
170
|
-
assert_equal 2, response.records.size
|
171
|
-
|
172
|
-
assert_equal 'Test', response.results.first.title
|
173
|
-
assert_equal 'Test', response.records.first.title
|
174
|
-
end
|
175
|
-
|
176
|
-
should "reindex a document after categories are changed" do
|
177
|
-
# Create categories
|
178
|
-
category_a = Category.where(title: "One").first_or_create!
|
179
|
-
category_b = Category.where(title: "Two").first_or_create!
|
180
|
-
|
181
|
-
# Create post
|
182
|
-
post = Post.create! title: "First Post", text: "This is the first post..."
|
183
|
-
|
184
|
-
# Assign categories
|
185
|
-
post.categories = [category_a, category_b]
|
186
|
-
|
187
|
-
Post.__elasticsearch__.refresh_index!
|
188
|
-
|
189
|
-
query = { query: {
|
190
|
-
bool: {
|
191
|
-
must: {
|
192
|
-
multi_match: {
|
193
|
-
fields: ['title'],
|
194
|
-
query: 'first'
|
195
|
-
}
|
196
|
-
},
|
197
|
-
filter: {
|
198
|
-
terms: {
|
199
|
-
categories: ['One']
|
200
|
-
}
|
201
|
-
}
|
202
|
-
}
|
203
|
-
}
|
204
|
-
}
|
205
|
-
|
206
|
-
response = Post.search query
|
207
|
-
|
208
|
-
assert_equal 1, response.results.size
|
209
|
-
assert_equal 1, response.records.size
|
210
|
-
|
211
|
-
# Remove category "One"
|
212
|
-
post.categories = [category_b]
|
213
|
-
|
214
|
-
Post.__elasticsearch__.refresh_index!
|
215
|
-
response = Post.search query
|
216
|
-
|
217
|
-
assert_equal 0, response.results.size
|
218
|
-
assert_equal 0, response.records.size
|
219
|
-
end
|
220
|
-
|
221
|
-
should "reindex a document after authors are changed" do
|
222
|
-
# Create authors
|
223
|
-
author_a = Author.where(first_name: "John", last_name: "Smith").first_or_create!
|
224
|
-
author_b = Author.where(first_name: "Mary", last_name: "Smith").first_or_create!
|
225
|
-
author_c = Author.where(first_name: "Kobe", last_name: "Griss").first_or_create!
|
226
|
-
|
227
|
-
# Create posts
|
228
|
-
post_1 = Post.create! title: "First Post", text: "This is the first post..."
|
229
|
-
post_2 = Post.create! title: "Second Post", text: "This is the second post..."
|
230
|
-
post_3 = Post.create! title: "Third Post", text: "This is the third post..."
|
231
|
-
|
232
|
-
# Assign authors
|
233
|
-
post_1.authors = [author_a, author_b]
|
234
|
-
post_2.authors = [author_a]
|
235
|
-
post_3.authors = [author_c]
|
236
|
-
|
237
|
-
Post.__elasticsearch__.refresh_index!
|
238
|
-
|
239
|
-
response = Post.search 'authors.full_name:john'
|
240
|
-
|
241
|
-
assert_equal 2, response.results.size
|
242
|
-
assert_equal 2, response.records.size
|
243
|
-
|
244
|
-
post_3.authors << author_a
|
245
|
-
|
246
|
-
Post.__elasticsearch__.refresh_index!
|
247
|
-
|
248
|
-
response = Post.search 'authors.full_name:john'
|
249
|
-
|
250
|
-
assert_equal 3, response.results.size
|
251
|
-
assert_equal 3, response.records.size
|
252
|
-
end if defined?(::ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 4
|
253
|
-
|
254
|
-
should "reindex a document after comments are added" do
|
255
|
-
# Create posts
|
256
|
-
post_1 = Post.create! title: "First Post", text: "This is the first post..."
|
257
|
-
post_2 = Post.create! title: "Second Post", text: "This is the second post..."
|
258
|
-
|
259
|
-
# Add comments
|
260
|
-
post_1.comments.create! author: 'John', text: 'Excellent'
|
261
|
-
post_1.comments.create! author: 'Abby', text: 'Good'
|
262
|
-
|
263
|
-
post_2.comments.create! author: 'John', text: 'Terrible'
|
264
|
-
|
265
|
-
Post.__elasticsearch__.refresh_index!
|
266
|
-
|
267
|
-
response = Post.search 'comments.author:john AND comments.text:good'
|
268
|
-
assert_equal 0, response.results.size
|
269
|
-
|
270
|
-
# Add comment
|
271
|
-
post_1.comments.create! author: 'John', text: 'Or rather just good...'
|
272
|
-
|
273
|
-
Post.__elasticsearch__.refresh_index!
|
274
|
-
|
275
|
-
response = Post.search 'comments.author:john AND comments.text:good'
|
276
|
-
assert_equal 0, response.results.size
|
277
|
-
|
278
|
-
response = Post.search \
|
279
|
-
query: {
|
280
|
-
nested: {
|
281
|
-
path: 'comments',
|
282
|
-
query: {
|
283
|
-
bool: {
|
284
|
-
must: [
|
285
|
-
{ match: { 'comments.author' => 'john' } },
|
286
|
-
{ match: { 'comments.text' => 'good' } }
|
287
|
-
]
|
288
|
-
}
|
289
|
-
}
|
290
|
-
}
|
291
|
-
}
|
292
|
-
|
293
|
-
assert_equal 1, response.results.size
|
294
|
-
end if defined?(::ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 4
|
295
|
-
|
296
|
-
should "reindex a document after Post#touch" do
|
297
|
-
# Create categories
|
298
|
-
category_a = Category.where(title: "One").first_or_create!
|
299
|
-
|
300
|
-
# Create post
|
301
|
-
post = Post.create! title: "First Post", text: "This is the first post..."
|
302
|
-
|
303
|
-
# Assign category
|
304
|
-
post.categories << category_a
|
305
|
-
|
306
|
-
Post.__elasticsearch__.refresh_index!
|
307
|
-
|
308
|
-
assert_equal 1, Post.search('categories:One').size
|
309
|
-
|
310
|
-
# Update category
|
311
|
-
category_a.update_attribute :title, "Updated"
|
312
|
-
|
313
|
-
# Trigger touch on posts in category
|
314
|
-
category_a.posts.each { |p| p.touch }
|
315
|
-
|
316
|
-
Post.__elasticsearch__.refresh_index!
|
317
|
-
|
318
|
-
assert_equal 0, Post.search('categories:One').size
|
319
|
-
assert_equal 1, Post.search('categories:Updated').size
|
320
|
-
end
|
321
|
-
|
322
|
-
should "eagerly load associated records" do
|
323
|
-
post_1 = Post.create(title: 'One')
|
324
|
-
post_2 = Post.create(title: 'Two')
|
325
|
-
post_1.comments.create text: 'First comment'
|
326
|
-
post_1.comments.create text: 'Second comment'
|
327
|
-
|
328
|
-
Comment.__elasticsearch__.refresh_index!
|
329
|
-
|
330
|
-
records = Comment.search('first').records(includes: :post)
|
331
|
-
|
332
|
-
assert records.first.association(:post).loaded?, "The associated Post should be eagerly loaded"
|
333
|
-
assert_equal 'One', records.first.post.title
|
334
|
-
end
|
335
|
-
end
|
336
|
-
|
337
|
-
end
|
338
|
-
end
|
339
|
-
end
|