elasticsearch-model 5.1.0 → 6.0.0.pre
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/README.md +4 -4
- data/elasticsearch-model.gemspec +4 -4
- data/examples/activerecord_custom_analyzer.rb +135 -0
- data/examples/activerecord_mapping_completion.rb +1 -3
- data/examples/datamapper_article.rb +11 -1
- data/gemfiles/3.0.gemfile +1 -1
- data/gemfiles/4.0.gemfile +1 -1
- data/gemfiles/5.0.gemfile +1 -1
- data/lib/elasticsearch/model/indexing.rb +1 -1
- data/lib/elasticsearch/model/naming.rb +3 -1
- data/lib/elasticsearch/model/version.rb +1 -1
- data/test/integration/active_record_associations_parent_child_test.rb +75 -34
- data/test/integration/active_record_basic_test.rb +2 -0
- data/test/integration/active_record_custom_serialization_test.rb +2 -2
- data/test/integration/active_record_namespaced_model_test.rb +2 -0
- data/test/test_helper.rb +1 -1
- data/test/unit/indexing_test.rb +35 -2
- data/test/unit/naming_inheritance_test.rb +2 -2
- data/test/unit/naming_test.rb +2 -2
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42c06d477404fd7b991c3af477e595f2e9ec662167cf264745ab43dff91d5e19
|
4
|
+
data.tar.gz: 58c05971c219d2cd14a0c91acd1675d20699e55f4944afc5a71d10acb60d3aaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d2b3ffc337dd8083cd4dcb6ea74555add7f427fbd7bf16734d76e46d0e4ad110f1c4f581ec1a23bb6dbb7540c131a9d08b659704e4c796ffa06d0ccc6474a0c
|
7
|
+
data.tar.gz: 3162fbfac4daa561507929333235124f99828c4c845f1bfbe19e18c853b06a8d2210559dc44de93184524e2fe2c09b5e96e7c6186691c2121339a7e8923ff94d
|
data/README.md
CHANGED
@@ -321,7 +321,7 @@ Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model
|
|
321
321
|
|
322
322
|
#### The Elasticsearch DSL
|
323
323
|
|
324
|
-
In most
|
324
|
+
In most situations, you'll want to pass the search definition
|
325
325
|
in the Elasticsearch [domain-specific language](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html) to the client:
|
326
326
|
|
327
327
|
```ruby
|
@@ -425,7 +425,7 @@ Article.__elasticsearch__.refresh_index!
|
|
425
425
|
```
|
426
426
|
|
427
427
|
By default, index name and document type will be inferred from your class name,
|
428
|
-
you can set it
|
428
|
+
you can set it explicitly, however:
|
429
429
|
|
430
430
|
```ruby
|
431
431
|
class Article
|
@@ -534,7 +534,7 @@ class Indexer
|
|
534
534
|
case operation.to_s
|
535
535
|
when /index/
|
536
536
|
record = Article.find(record_id)
|
537
|
-
Client.index index: 'articles', type: 'article', id: record.id, body: record.as_indexed_json
|
537
|
+
Client.index index: 'articles', type: 'article', id: record.id, body: record.__elasticsearch__.as_indexed_json
|
538
538
|
when /delete/
|
539
539
|
Client.delete index: 'articles', type: 'article', id: record_id
|
540
540
|
else raise ArgumentError, "Unknown operation '#{operation}'"
|
@@ -674,7 +674,7 @@ module DataMapperAdapter
|
|
674
674
|
#
|
675
675
|
module Records
|
676
676
|
def records
|
677
|
-
klass.all(id:
|
677
|
+
klass.all(id: ids)
|
678
678
|
end
|
679
679
|
|
680
680
|
# ...
|
data/elasticsearch-model.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
|
24
24
|
s.required_ruby_version = ">= 1.9.3"
|
25
25
|
|
26
|
-
s.add_dependency "elasticsearch", '
|
26
|
+
s.add_dependency "elasticsearch", '> 1'
|
27
27
|
s.add_dependency "activesupport", '> 3'
|
28
28
|
s.add_dependency "hashie"
|
29
29
|
|
@@ -32,10 +32,10 @@ Gem::Specification.new do |s|
|
|
32
32
|
|
33
33
|
s.add_development_dependency "elasticsearch-extensions"
|
34
34
|
|
35
|
-
s.add_development_dependency "sqlite3"
|
35
|
+
s.add_development_dependency "sqlite3" unless defined?(JRUBY_VERSION)
|
36
36
|
s.add_development_dependency "activemodel", "> 3"
|
37
37
|
|
38
|
-
s.add_development_dependency "oj"
|
38
|
+
s.add_development_dependency "oj" unless defined?(JRUBY_VERSION)
|
39
39
|
s.add_development_dependency "kaminari"
|
40
40
|
s.add_development_dependency "will_paginate"
|
41
41
|
|
@@ -45,7 +45,7 @@ Gem::Specification.new do |s|
|
|
45
45
|
s.add_development_dependency "mocha"
|
46
46
|
s.add_development_dependency "turn"
|
47
47
|
s.add_development_dependency "yard"
|
48
|
-
s.add_development_dependency "ruby-prof"
|
48
|
+
s.add_development_dependency "ruby-prof" unless defined?(JRUBY_VERSION)
|
49
49
|
s.add_development_dependency "pry"
|
50
50
|
|
51
51
|
s.add_development_dependency "simplecov"
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# Custom Analyzer for ActiveRecord integration with Elasticsearch
|
2
|
+
# ===============================================================
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
5
|
+
|
6
|
+
require 'ansi'
|
7
|
+
require 'logger'
|
8
|
+
|
9
|
+
require 'active_record'
|
10
|
+
require 'elasticsearch/model'
|
11
|
+
|
12
|
+
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
|
13
|
+
ActiveRecord::Base.establish_connection( adapter: 'sqlite3', database: ":memory:" )
|
14
|
+
|
15
|
+
ActiveRecord::Schema.define(version: 1) do
|
16
|
+
create_table :articles do |t|
|
17
|
+
t.string :title
|
18
|
+
t.date :published_at
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Elasticsearch::Model.client.transport.logger = ActiveSupport::Logger.new(STDOUT)
|
24
|
+
Elasticsearch::Model.client.transport.logger.formatter = lambda { |s, d, p, m| "#{m.ansi(:faint)}\n" }
|
25
|
+
|
26
|
+
class Article < ActiveRecord::Base
|
27
|
+
include Elasticsearch::Model
|
28
|
+
|
29
|
+
settings index: {
|
30
|
+
number_of_shards: 1,
|
31
|
+
number_of_replicas: 0,
|
32
|
+
analysis: {
|
33
|
+
analyzer: {
|
34
|
+
pattern: {
|
35
|
+
type: 'pattern',
|
36
|
+
pattern: "\\s|_|-|\\.",
|
37
|
+
lowercase: true
|
38
|
+
},
|
39
|
+
trigram: {
|
40
|
+
tokenizer: 'trigram'
|
41
|
+
}
|
42
|
+
},
|
43
|
+
tokenizer: {
|
44
|
+
trigram: {
|
45
|
+
type: 'ngram',
|
46
|
+
min_gram: 3,
|
47
|
+
max_gram: 3,
|
48
|
+
token_chars: ['letter', 'digit']
|
49
|
+
}
|
50
|
+
}
|
51
|
+
} } do
|
52
|
+
mapping do
|
53
|
+
indexes :title, type: 'text', analyzer: 'english' do
|
54
|
+
indexes :keyword, analyzer: 'keyword'
|
55
|
+
indexes :pattern, analyzer: 'pattern'
|
56
|
+
indexes :trigram, analyzer: 'trigram'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Create example records
|
63
|
+
#
|
64
|
+
Article.delete_all
|
65
|
+
Article.create title: 'Foo'
|
66
|
+
Article.create title: 'Foo-Bar'
|
67
|
+
Article.create title: 'Foo_Bar_Bazooka'
|
68
|
+
Article.create title: 'Foo.Bar'
|
69
|
+
|
70
|
+
# Index records
|
71
|
+
#
|
72
|
+
errors = Article.import force: true, refresh: true, return: 'errors'
|
73
|
+
puts "[!] Errors importing records: #{errors.map { |d| d['index']['error'] }.join(', ')}".ansi(:red) && exit(1) unless errors.empty?
|
74
|
+
|
75
|
+
puts '', '-'*80
|
76
|
+
|
77
|
+
puts "English analyzer [Foo_Bar_1_Bazooka]".ansi(:bold),
|
78
|
+
"Tokens: " +
|
79
|
+
Article.__elasticsearch__.client.indices
|
80
|
+
.analyze(index: Article.index_name, body: { field: 'title', text: 'Foo_Bar_1_Bazooka' })['tokens']
|
81
|
+
.map { |d| "[#{d['token']}]" }.join(' '),
|
82
|
+
"\n"
|
83
|
+
|
84
|
+
puts "Keyword analyzer [Foo_Bar_1_Bazooka]".ansi(:bold),
|
85
|
+
"Tokens: " +
|
86
|
+
Article.__elasticsearch__.client.indices
|
87
|
+
.analyze(index: Article.index_name, body: { field: 'title.keyword', text: 'Foo_Bar_1_Bazooka' })['tokens']
|
88
|
+
.map { |d| "[#{d['token']}]" }.join(' '),
|
89
|
+
"\n"
|
90
|
+
|
91
|
+
puts "Pattern analyzer [Foo_Bar_1_Bazooka]".ansi(:bold),
|
92
|
+
"Tokens: " +
|
93
|
+
Article.__elasticsearch__.client.indices
|
94
|
+
.analyze(index: Article.index_name, body: { field: 'title.pattern', text: 'Foo_Bar_1_Bazooka' })['tokens']
|
95
|
+
.map { |d| "[#{d['token']}]" }.join(' '),
|
96
|
+
"\n"
|
97
|
+
|
98
|
+
puts "Trigram analyzer [Foo_Bar_1_Bazooka]".ansi(:bold),
|
99
|
+
"Tokens: " +
|
100
|
+
Article.__elasticsearch__.client.indices
|
101
|
+
.analyze(index: Article.index_name, body: { field: 'title.trigram', text: 'Foo_Bar_1_Bazooka' })['tokens']
|
102
|
+
.map { |d| "[#{d['token']}]" }.join(' '),
|
103
|
+
"\n"
|
104
|
+
|
105
|
+
puts '', '-'*80
|
106
|
+
|
107
|
+
response = Article.search query: { match: { 'title' => 'foo' } } ;
|
108
|
+
|
109
|
+
puts "English search for 'foo'".ansi(:bold),
|
110
|
+
"#{response.response.hits.total} matches: " +
|
111
|
+
response.records.map { |d| d.title }.join(', '),
|
112
|
+
"\n"
|
113
|
+
|
114
|
+
puts '', '-'*80
|
115
|
+
|
116
|
+
response = Article.search query: { match: { 'title.pattern' => 'foo' } } ;
|
117
|
+
|
118
|
+
puts "Pattern search for 'foo'".ansi(:bold),
|
119
|
+
"#{response.response.hits.total} matches: " +
|
120
|
+
response.records.map { |d| d.title }.join(', '),
|
121
|
+
"\n"
|
122
|
+
|
123
|
+
puts '', '-'*80
|
124
|
+
|
125
|
+
response = Article.search query: { match: { 'title.trigram' => 'zoo' } } ;
|
126
|
+
|
127
|
+
puts "Trigram search for 'zoo'".ansi(:bold),
|
128
|
+
"#{response.response.hits.total} matches: " +
|
129
|
+
response.records.map { |d| d.title }.join(', '),
|
130
|
+
"\n"
|
131
|
+
|
132
|
+
puts '', '-'*80
|
133
|
+
|
134
|
+
|
135
|
+
require 'pry'; binding.pry;
|
@@ -50,11 +50,21 @@ module DataMapperAdapter
|
|
50
50
|
#
|
51
51
|
module Records
|
52
52
|
def records
|
53
|
-
klass.all(id:
|
53
|
+
klass.all(id: ids)
|
54
54
|
end
|
55
55
|
|
56
56
|
# ...
|
57
57
|
end
|
58
|
+
|
59
|
+
module Callbacks
|
60
|
+
def self.included(model)
|
61
|
+
model.class_eval do
|
62
|
+
after(:create) { __elasticsearch__.index_document }
|
63
|
+
after(:save) { __elasticsearch__.update_document }
|
64
|
+
after(:destroy) { __elasticsearch__.delete_document }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
58
68
|
end
|
59
69
|
|
60
70
|
# Register the adapter
|
data/gemfiles/3.0.gemfile
CHANGED
data/gemfiles/4.0.gemfile
CHANGED
data/gemfiles/5.0.gemfile
CHANGED
@@ -397,7 +397,7 @@ module Elasticsearch
|
|
397
397
|
# @see http://rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions:update
|
398
398
|
#
|
399
399
|
def update_document(options={})
|
400
|
-
if attributes_in_database = self.instance_variable_get(:@__changed_model_attributes)
|
400
|
+
if attributes_in_database = self.instance_variable_get(:@__changed_model_attributes).presence
|
401
401
|
attributes = if respond_to?(:as_indexed_json)
|
402
402
|
self.as_indexed_json.select { |k,v| attributes_in_database.keys.map(&:to_s).include? k.to_s }
|
403
403
|
else
|
@@ -5,6 +5,8 @@ module Elasticsearch
|
|
5
5
|
#
|
6
6
|
module Naming
|
7
7
|
|
8
|
+
DEFAULT_DOC_TYPE = '_doc'.freeze
|
9
|
+
|
8
10
|
module ClassMethods
|
9
11
|
|
10
12
|
# Get or set the name of the index
|
@@ -90,7 +92,7 @@ module Elasticsearch
|
|
90
92
|
end
|
91
93
|
|
92
94
|
def default_document_type
|
93
|
-
|
95
|
+
DEFAULT_DOC_TYPE
|
94
96
|
end
|
95
97
|
|
96
98
|
end
|
@@ -11,7 +11,11 @@ class Question < ActiveRecord::Base
|
|
11
11
|
|
12
12
|
has_many :answers, dependent: :destroy
|
13
13
|
|
14
|
-
|
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
|
15
19
|
|
16
20
|
mapping do
|
17
21
|
indexes :title
|
@@ -19,6 +23,12 @@ class Question < ActiveRecord::Base
|
|
19
23
|
indexes :author
|
20
24
|
end
|
21
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
|
+
|
22
32
|
after_commit lambda { __elasticsearch__.index_document }, on: :create
|
23
33
|
after_commit lambda { __elasticsearch__.update_document }, on: :update
|
24
34
|
after_commit lambda { __elasticsearch__.delete_document }, on: :destroy
|
@@ -29,32 +39,55 @@ class Answer < ActiveRecord::Base
|
|
29
39
|
|
30
40
|
belongs_to :question
|
31
41
|
|
32
|
-
|
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
|
33
54
|
|
34
|
-
mapping
|
55
|
+
mapping do
|
35
56
|
indexes :text
|
36
57
|
indexes :author
|
37
58
|
end
|
38
59
|
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
42
69
|
end
|
43
70
|
|
44
71
|
module ParentChildSearchable
|
45
|
-
INDEX_NAME = 'questions_and_answers'
|
72
|
+
INDEX_NAME = 'questions_and_answers'.freeze
|
73
|
+
JOIN = 'join'.freeze
|
46
74
|
|
47
75
|
def create_index!(options={})
|
48
76
|
client = Question.__elasticsearch__.client
|
49
77
|
client.indices.delete index: INDEX_NAME rescue nil if options[:force]
|
50
78
|
|
51
79
|
settings = Question.settings.to_hash.merge Answer.settings.to_hash
|
52
|
-
|
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 }}
|
53
86
|
|
54
87
|
client.indices.create index: INDEX_NAME,
|
55
88
|
body: {
|
56
|
-
|
57
|
-
|
89
|
+
settings: settings.to_hash,
|
90
|
+
mappings: mappings }
|
58
91
|
end
|
59
92
|
|
60
93
|
extend self
|
@@ -100,34 +133,34 @@ module Elasticsearch
|
|
100
133
|
|
101
134
|
should "find questions by matching answers" do
|
102
135
|
response = Question.search(
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
136
|
+
{ query: {
|
137
|
+
has_child: {
|
138
|
+
type: 'answer',
|
139
|
+
query: {
|
140
|
+
match: {
|
141
|
+
author: 'john'
|
142
|
+
}
|
143
|
+
}
|
144
|
+
}
|
145
|
+
}
|
146
|
+
})
|
114
147
|
|
115
148
|
assert_equal 'Second Question', response.records.first.title
|
116
149
|
end
|
117
150
|
|
118
151
|
should "find answers for matching questions" do
|
119
152
|
response = Answer.search(
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
153
|
+
{ query: {
|
154
|
+
has_parent: {
|
155
|
+
parent_type: 'question',
|
156
|
+
query: {
|
157
|
+
match: {
|
158
|
+
author: 'john'
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|
163
|
+
})
|
131
164
|
|
132
165
|
assert_same_elements ['Adam', 'Ryan'], response.records.map(&:author)
|
133
166
|
end
|
@@ -136,12 +169,20 @@ module Elasticsearch
|
|
136
169
|
Question.where(title: 'First Question').each(&:destroy)
|
137
170
|
Question.__elasticsearch__.refresh_index!
|
138
171
|
|
139
|
-
response = Answer.search
|
172
|
+
response = Answer.search(
|
173
|
+
{ query: {
|
174
|
+
has_parent: {
|
175
|
+
parent_type: 'question',
|
176
|
+
query: {
|
177
|
+
match_all: {}
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
})
|
140
182
|
|
141
183
|
assert_equal 1, response.results.total
|
142
184
|
end
|
143
185
|
end
|
144
|
-
|
145
186
|
end
|
146
187
|
end
|
147
188
|
end
|
@@ -16,6 +16,8 @@ module Elasticsearch
|
|
16
16
|
include Elasticsearch::Model
|
17
17
|
include Elasticsearch::Model::Callbacks
|
18
18
|
|
19
|
+
document_type 'article'
|
20
|
+
|
19
21
|
settings index: { number_of_shards: 1, number_of_replicas: 0 } do
|
20
22
|
mapping do
|
21
23
|
indexes :title, type: 'text', analyzer: 'snowball'
|
@@ -41,7 +41,7 @@ module Elasticsearch
|
|
41
41
|
|
42
42
|
a = ArticleWithCustomSerialization.__elasticsearch__.client.get \
|
43
43
|
index: 'article_with_custom_serializations',
|
44
|
-
type: '
|
44
|
+
type: '_doc',
|
45
45
|
id: '1'
|
46
46
|
|
47
47
|
assert_equal( { 'title' => 'Test' }, a['_source'] )
|
@@ -55,7 +55,7 @@ module Elasticsearch
|
|
55
55
|
|
56
56
|
a = ArticleWithCustomSerialization.__elasticsearch__.client.get \
|
57
57
|
index: 'article_with_custom_serializations',
|
58
|
-
type: '
|
58
|
+
type: '_doc',
|
59
59
|
id: '1'
|
60
60
|
|
61
61
|
assert_equal( { 'title' => 'UPDATED' }, a['_source'] )
|
data/test/test_helper.rb
CHANGED
data/test/unit/indexing_test.rb
CHANGED
@@ -149,7 +149,7 @@ class Elasticsearch::Model::IndexingTest < Test::Unit::TestCase
|
|
149
149
|
should "update and return the index mappings" do
|
150
150
|
DummyIndexingModel.mappings foo: 'boo'
|
151
151
|
DummyIndexingModel.mappings bar: 'bam'
|
152
|
-
assert_equal( {
|
152
|
+
assert_equal( { _doc: { foo: "boo", bar: "bam", properties: {} } },
|
153
153
|
DummyIndexingModel.mappings.to_hash )
|
154
154
|
end
|
155
155
|
|
@@ -176,6 +176,19 @@ class Elasticsearch::Model::IndexingTest < Test::Unit::TestCase
|
|
176
176
|
end
|
177
177
|
end
|
178
178
|
|
179
|
+
class ::DummyIndexingModelWithNoChanges
|
180
|
+
extend Elasticsearch::Model::Indexing::ClassMethods
|
181
|
+
include Elasticsearch::Model::Indexing::InstanceMethods
|
182
|
+
|
183
|
+
def self.before_save(&block)
|
184
|
+
(@callbacks ||= {})[block.hash] = block
|
185
|
+
end
|
186
|
+
|
187
|
+
def changes_to_save
|
188
|
+
{}
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
179
192
|
class ::DummyIndexingModelWithCallbacksAndCustomAsIndexedJson
|
180
193
|
extend Elasticsearch::Model::Indexing::ClassMethods
|
181
194
|
include Elasticsearch::Model::Indexing::InstanceMethods
|
@@ -393,6 +406,26 @@ class Elasticsearch::Model::IndexingTest < Test::Unit::TestCase
|
|
393
406
|
instance.update_document
|
394
407
|
end
|
395
408
|
|
409
|
+
should "index instead of update when nothing was changed" do
|
410
|
+
client = mock('client')
|
411
|
+
instance = ::DummyIndexingModelWithNoChanges.new
|
412
|
+
|
413
|
+
# Set the fake `changes` hash
|
414
|
+
instance.instance_variable_set(:@__changed_model_attributes, {})
|
415
|
+
# Overload as_indexed_json for running index
|
416
|
+
instance.expects(:as_indexed_json).returns({ 'foo' => 'BAR' })
|
417
|
+
|
418
|
+
client.expects(:index)
|
419
|
+
client.expects(:update).never
|
420
|
+
|
421
|
+
instance.expects(:client).returns(client)
|
422
|
+
instance.expects(:index_name).returns('foo')
|
423
|
+
instance.expects(:document_type).returns('bar')
|
424
|
+
instance.expects(:id).returns('1')
|
425
|
+
|
426
|
+
instance.update_document({})
|
427
|
+
end
|
428
|
+
|
396
429
|
should "update only the specific attributes" do
|
397
430
|
client = mock('client')
|
398
431
|
instance = ::DummyIndexingModelWithCallbacks.new
|
@@ -544,7 +577,7 @@ class Elasticsearch::Model::IndexingTest < Test::Unit::TestCase
|
|
544
577
|
indices.expects(:create).with do |payload|
|
545
578
|
assert_equal 'dummy_indexing_model_for_recreates', payload[:index]
|
546
579
|
assert_equal 1, payload[:body][:settings][:index][:number_of_shards]
|
547
|
-
assert_equal 'keyword', payload[:body][:mappings][:
|
580
|
+
assert_equal 'keyword', payload[:body][:mappings][:_doc][:properties][:foo][:analyzer]
|
548
581
|
true
|
549
582
|
end.returns({})
|
550
583
|
|
@@ -69,8 +69,8 @@ class Elasticsearch::Model::NamingInheritanceTest < Test::Unit::TestCase
|
|
69
69
|
end
|
70
70
|
|
71
71
|
should "return the default document_type" do
|
72
|
-
assert_equal "
|
73
|
-
assert_equal "
|
72
|
+
assert_equal "_doc", TestBase.document_type
|
73
|
+
assert_equal "_doc", TestBase.new.document_type
|
74
74
|
end
|
75
75
|
|
76
76
|
should "return the explicit document_type" do
|
data/test/unit/naming_test.rb
CHANGED
@@ -29,8 +29,8 @@ class Elasticsearch::Model::NamingTest < Test::Unit::TestCase
|
|
29
29
|
end
|
30
30
|
|
31
31
|
should "return the default document_type" do
|
32
|
-
assert_equal '
|
33
|
-
assert_equal '
|
32
|
+
assert_equal '_doc', DummyNamingModel.document_type
|
33
|
+
assert_equal '_doc', DummyNamingModel.new.document_type
|
34
34
|
end
|
35
35
|
|
36
36
|
should "set and return the index_name" do
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elasticsearch-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Karel Minarik
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: elasticsearch
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -336,6 +336,7 @@ files:
|
|
336
336
|
- elasticsearch-model.gemspec
|
337
337
|
- examples/activerecord_article.rb
|
338
338
|
- examples/activerecord_associations.rb
|
339
|
+
- examples/activerecord_custom_analyzer.rb
|
339
340
|
- examples/activerecord_mapping_completion.rb
|
340
341
|
- examples/activerecord_mapping_edge_ngram.rb
|
341
342
|
- examples/couchbase_article.rb
|
@@ -427,12 +428,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
427
428
|
version: 1.9.3
|
428
429
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
429
430
|
requirements:
|
430
|
-
- - "
|
431
|
+
- - ">"
|
431
432
|
- !ruby/object:Gem::Version
|
432
|
-
version:
|
433
|
+
version: 1.3.1
|
433
434
|
requirements: []
|
434
435
|
rubyforge_project:
|
435
|
-
rubygems_version: 2.7.
|
436
|
+
rubygems_version: 2.7.7
|
436
437
|
signing_key:
|
437
438
|
specification_version: 4
|
438
439
|
summary: ActiveModel/Record integrations for Elasticsearch.
|