elasticsearch-model 6.1.1 → 7.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/.gitignore +3 -1
- data/Gemfile +17 -0
- data/LICENSE.txt +199 -10
- data/README.md +17 -16
- data/Rakefile +18 -1
- data/elasticsearch-model.gemspec +19 -2
- data/examples/activerecord_article.rb +17 -0
- data/examples/activerecord_associations.rb +17 -0
- data/examples/activerecord_custom_analyzer.rb +17 -0
- data/examples/activerecord_mapping_completion.rb +17 -0
- data/examples/activerecord_mapping_edge_ngram.rb +17 -0
- data/examples/couchbase_article.rb +17 -0
- data/examples/datamapper_article.rb +17 -0
- data/examples/mongoid_article.rb +17 -0
- data/examples/ohm_article.rb +17 -0
- data/examples/riak_article.rb +17 -0
- data/gemfiles/3.0.gemfile +18 -1
- data/gemfiles/4.0.gemfile +20 -4
- data/gemfiles/5.0.gemfile +18 -1
- data/gemfiles/6.0.gemfile +21 -3
- data/lib/elasticsearch/model.rb +25 -15
- data/lib/elasticsearch/model/adapter.rb +17 -0
- data/lib/elasticsearch/model/adapters/active_record.rb +18 -1
- data/lib/elasticsearch/model/adapters/default.rb +17 -0
- data/lib/elasticsearch/model/adapters/mongoid.rb +17 -0
- data/lib/elasticsearch/model/adapters/multiple.rb +29 -4
- data/lib/elasticsearch/model/callbacks.rb +17 -0
- data/lib/elasticsearch/model/client.rb +17 -0
- data/lib/elasticsearch/model/ext/active_record.rb +17 -0
- data/lib/elasticsearch/model/hash_wrapper.rb +17 -0
- data/lib/elasticsearch/model/importing.rb +17 -0
- data/lib/elasticsearch/model/indexing.rb +29 -8
- data/lib/elasticsearch/model/multimodel.rb +17 -0
- data/lib/elasticsearch/model/naming.rb +19 -10
- data/lib/elasticsearch/model/proxy.rb +17 -0
- data/lib/elasticsearch/model/response.rb +17 -0
- data/lib/elasticsearch/model/response/aggregations.rb +17 -0
- data/lib/elasticsearch/model/response/base.rb +22 -1
- data/lib/elasticsearch/model/response/pagination.rb +17 -0
- data/lib/elasticsearch/model/response/pagination/kaminari.rb +17 -0
- data/lib/elasticsearch/model/response/pagination/will_paginate.rb +17 -0
- data/lib/elasticsearch/model/response/records.rb +17 -0
- data/lib/elasticsearch/model/response/result.rb +17 -0
- data/lib/elasticsearch/model/response/results.rb +17 -0
- data/lib/elasticsearch/model/response/suggestions.rb +17 -0
- data/lib/elasticsearch/model/searching.rb +17 -0
- data/lib/elasticsearch/model/serializing.rb +17 -0
- data/lib/elasticsearch/model/version.rb +18 -1
- data/spec/elasticsearch/model/adapter_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/active_record/associations_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/active_record/basic_spec.rb +281 -226
- data/spec/elasticsearch/model/adapters/active_record/dynamic_index_name_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/active_record/import_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/active_record/multi_model_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/active_record/namespaced_model_spec.rb +18 -1
- data/spec/elasticsearch/model/adapters/active_record/pagination_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/active_record/parent_child_spec.rb +18 -1
- data/spec/elasticsearch/model/adapters/active_record/serialization_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/active_record_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/default_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/mongoid/basic_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/mongoid/multi_model_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/mongoid_spec.rb +17 -0
- data/spec/elasticsearch/model/adapters/multiple_spec.rb +17 -0
- data/spec/elasticsearch/model/callbacks_spec.rb +17 -0
- data/spec/elasticsearch/model/client_spec.rb +17 -0
- data/spec/elasticsearch/model/hash_wrapper_spec.rb +17 -0
- data/spec/elasticsearch/model/importing_spec.rb +17 -0
- data/spec/elasticsearch/model/indexing_spec.rb +108 -12
- data/spec/elasticsearch/model/module_spec.rb +17 -25
- data/spec/elasticsearch/model/multimodel_spec.rb +17 -0
- data/spec/elasticsearch/model/naming_inheritance_spec.rb +82 -143
- data/spec/elasticsearch/model/naming_spec.rb +22 -5
- data/spec/elasticsearch/model/proxy_spec.rb +17 -0
- data/spec/elasticsearch/model/response/aggregations_spec.rb +17 -0
- data/spec/elasticsearch/model/response/base_spec.rb +17 -0
- data/spec/elasticsearch/model/response/pagination/kaminari_spec.rb +85 -23
- data/spec/elasticsearch/model/response/pagination/will_paginate_spec.rb +17 -0
- data/spec/elasticsearch/model/response/records_spec.rb +17 -0
- data/spec/elasticsearch/model/response/response_spec.rb +17 -0
- data/spec/elasticsearch/model/response/result_spec.rb +17 -0
- data/spec/elasticsearch/model/response/results_spec.rb +17 -0
- data/spec/elasticsearch/model/searching_search_request_spec.rb +17 -0
- data/spec/elasticsearch/model/searching_spec.rb +17 -0
- data/spec/elasticsearch/model/serializing_spec.rb +17 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/app.rb +18 -0
- data/spec/support/app/answer.rb +17 -0
- data/spec/support/app/article.rb +17 -0
- data/spec/support/app/article_for_pagination.rb +17 -0
- data/spec/support/app/article_no_type.rb +37 -0
- data/spec/support/app/article_with_custom_serialization.rb +17 -0
- data/spec/support/app/article_with_dynamic_index_name.rb +17 -0
- data/spec/support/app/author.rb +17 -0
- data/spec/support/app/authorship.rb +17 -0
- data/spec/support/app/category.rb +17 -0
- data/spec/support/app/comment.rb +17 -0
- data/spec/support/app/episode.rb +17 -0
- data/spec/support/app/image.rb +17 -0
- data/spec/support/app/import_article.rb +17 -0
- data/spec/support/app/mongoid_article.rb +17 -0
- data/spec/support/app/namespaced_book.rb +17 -0
- data/spec/support/app/parent_and_child_searchable.rb +21 -4
- data/spec/support/app/post.rb +17 -0
- data/spec/support/app/question.rb +17 -0
- data/spec/support/app/searchable.rb +17 -0
- data/spec/support/app/series.rb +17 -0
- metadata +12 -10
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
|
3
|
+
# this work for additional information regarding copyright
|
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
|
6
|
+
# not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
1
18
|
module Elasticsearch
|
|
2
19
|
module Model
|
|
3
20
|
module Response
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
|
3
|
+
# this work for additional information regarding copyright
|
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
|
6
|
+
# not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
1
18
|
module Elasticsearch
|
|
2
19
|
module Model
|
|
3
20
|
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
|
3
|
+
# this work for additional information regarding copyright
|
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
|
6
|
+
# not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
1
18
|
module Elasticsearch
|
|
2
19
|
module Model
|
|
3
20
|
|
|
@@ -1,5 +1,22 @@
|
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
|
3
|
+
# this work for additional information regarding copyright
|
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
|
6
|
+
# not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
1
18
|
module Elasticsearch
|
|
2
19
|
module Model
|
|
3
|
-
VERSION =
|
|
20
|
+
VERSION = "7.0.0.pre"
|
|
4
21
|
end
|
|
5
22
|
end
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
|
3
|
+
# this work for additional information regarding copyright
|
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
|
6
|
+
# not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
1
18
|
require 'spec_helper'
|
|
2
19
|
|
|
3
20
|
describe Elasticsearch::Model::Adapter do
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
|
3
|
+
# this work for additional information regarding copyright
|
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
|
6
|
+
# not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
1
18
|
require 'spec_helper'
|
|
2
19
|
|
|
3
20
|
describe 'Elasticsearch::Model::Adapter::ActiveRecord Associations' do
|
|
@@ -1,340 +1,395 @@
|
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
|
3
|
+
# this work for additional information regarding copyright
|
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
|
6
|
+
# not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
|
12
|
+
# software distributed under the License is distributed on an
|
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
# KIND, either express or implied. See the License for the
|
|
15
|
+
# specific language governing permissions and limitations
|
|
16
|
+
# under the License.
|
|
17
|
+
|
|
1
18
|
require 'spec_helper'
|
|
2
19
|
|
|
3
20
|
describe Elasticsearch::Model::Adapter::ActiveRecord do
|
|
4
21
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
t
|
|
10
|
-
|
|
11
|
-
|
|
22
|
+
context 'when a document_type is not defined for the Model' do
|
|
23
|
+
|
|
24
|
+
before do
|
|
25
|
+
ActiveRecord::Schema.define(:version => 1) do
|
|
26
|
+
create_table :article_no_types do |t|
|
|
27
|
+
t.string :title
|
|
28
|
+
t.string :body
|
|
29
|
+
t.integer :clicks, :default => 0
|
|
30
|
+
t.datetime :created_at, :default => 'NOW()'
|
|
31
|
+
end
|
|
12
32
|
end
|
|
13
|
-
end
|
|
14
33
|
|
|
15
|
-
|
|
16
|
-
|
|
34
|
+
ArticleNoType.delete_all
|
|
35
|
+
ArticleNoType.__elasticsearch__.create_index!(force: true)
|
|
17
36
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
37
|
+
ArticleNoType.create!(title: 'Test', body: '', clicks: 1)
|
|
38
|
+
ArticleNoType.create!(title: 'Testing Coding', body: '', clicks: 2)
|
|
39
|
+
ArticleNoType.create!(title: 'Coding', body: '', clicks: 3)
|
|
21
40
|
|
|
22
|
-
|
|
23
|
-
|
|
41
|
+
ArticleNoType.__elasticsearch__.refresh_index!
|
|
42
|
+
end
|
|
24
43
|
|
|
25
|
-
|
|
44
|
+
describe 'indexing a document' do
|
|
26
45
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
46
|
+
let(:search_result) do
|
|
47
|
+
ArticleNoType.search('title:test')
|
|
48
|
+
end
|
|
30
49
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
50
|
+
it 'allows searching for documents' do
|
|
51
|
+
expect(search_result.results.size).to be(2)
|
|
52
|
+
expect(search_result.records.size).to be(2)
|
|
53
|
+
end
|
|
34
54
|
end
|
|
35
55
|
end
|
|
36
56
|
|
|
37
|
-
|
|
57
|
+
context 'when a document_type is defined for the Model' do
|
|
38
58
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
59
|
+
before(:all) do
|
|
60
|
+
ActiveRecord::Schema.define(:version => 1) do
|
|
61
|
+
create_table :articles do |t|
|
|
62
|
+
t.string :title
|
|
63
|
+
t.string :body
|
|
64
|
+
t.integer :clicks, :default => 0
|
|
65
|
+
t.datetime :created_at, :default => 'NOW()'
|
|
66
|
+
end
|
|
67
|
+
end
|
|
42
68
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
end
|
|
69
|
+
Article.delete_all
|
|
70
|
+
Article.__elasticsearch__.create_index!(force: true, include_type_name: true)
|
|
46
71
|
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
Article.create!(title: 'Test', body: '', clicks: 1)
|
|
73
|
+
Article.create!(title: 'Testing Coding', body: '', clicks: 2)
|
|
74
|
+
Article.create!(title: 'Coding', body: '', clicks: 3)
|
|
75
|
+
|
|
76
|
+
Article.__elasticsearch__.refresh_index!
|
|
49
77
|
end
|
|
50
78
|
|
|
51
|
-
|
|
79
|
+
describe 'indexing a document' do
|
|
52
80
|
|
|
53
81
|
let(:search_result) do
|
|
54
|
-
Article.search(
|
|
82
|
+
Article.search('title:test')
|
|
55
83
|
end
|
|
56
84
|
|
|
57
|
-
it 'allows
|
|
58
|
-
expect(search_result.results.
|
|
59
|
-
expect(search_result.
|
|
60
|
-
expect(search_result.results.first.boo?).to be(false)
|
|
61
|
-
expect(search_result.results.first.highlight?).to be(true)
|
|
62
|
-
expect(search_result.results.first.highlight.title?).to be(true)
|
|
63
|
-
expect(search_result.results.first.highlight.boo?).to be(false)
|
|
85
|
+
it 'allows searching for documents' do
|
|
86
|
+
expect(search_result.results.size).to be(2)
|
|
87
|
+
expect(search_result.records.size).to be(2)
|
|
64
88
|
end
|
|
65
89
|
end
|
|
66
|
-
end
|
|
67
90
|
|
|
68
|
-
|
|
91
|
+
describe '#results' do
|
|
69
92
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
it 'returns an instance of the model' do
|
|
75
|
-
expect(search_result.records.first).to be_a(Article)
|
|
76
|
-
end
|
|
93
|
+
let(:search_result) do
|
|
94
|
+
Article.search('title:test')
|
|
95
|
+
end
|
|
77
96
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
end
|
|
97
|
+
it 'returns an instance of Response::Result' do
|
|
98
|
+
expect(search_result.results.first).to be_a(Elasticsearch::Model::Response::Result)
|
|
99
|
+
end
|
|
82
100
|
|
|
83
|
-
|
|
101
|
+
it 'prooperly loads the document' do
|
|
102
|
+
expect(search_result.results.first.title).to eq('Test')
|
|
103
|
+
end
|
|
84
104
|
|
|
85
|
-
|
|
86
|
-
Article.search('title:test')
|
|
87
|
-
end
|
|
105
|
+
context 'when the result contains other data' do
|
|
88
106
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
107
|
+
let(:search_result) do
|
|
108
|
+
Article.search(query: { match: { title: 'test' } }, highlight: { fields: { title: {} } })
|
|
109
|
+
end
|
|
92
110
|
|
|
93
|
-
|
|
94
|
-
|
|
111
|
+
it 'allows access to the Elasticsearch result' do
|
|
112
|
+
expect(search_result.results.first.title).to eq('Test')
|
|
113
|
+
expect(search_result.results.first.title?).to be(true)
|
|
114
|
+
expect(search_result.results.first.boo?).to be(false)
|
|
115
|
+
expect(search_result.results.first.highlight?).to be(true)
|
|
116
|
+
expect(search_result.results.first.highlight.title?).to be(true)
|
|
117
|
+
expect(search_result.results.first.highlight.boo?).to be(false)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
95
120
|
end
|
|
96
|
-
end
|
|
97
121
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
let(:search_result) do
|
|
101
|
-
Article.search('title:test')
|
|
102
|
-
end
|
|
122
|
+
describe '#records' do
|
|
103
123
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
end
|
|
124
|
+
let(:search_result) do
|
|
125
|
+
Article.search('title:test')
|
|
126
|
+
end
|
|
108
127
|
|
|
109
|
-
|
|
128
|
+
it 'returns an instance of the model' do
|
|
129
|
+
expect(search_result.records.first).to be_a(Article)
|
|
130
|
+
end
|
|
110
131
|
|
|
111
|
-
|
|
112
|
-
|
|
132
|
+
it 'prooperly loads the document' do
|
|
133
|
+
expect(search_result.records.first.title).to eq('Test')
|
|
134
|
+
end
|
|
113
135
|
end
|
|
114
136
|
|
|
115
|
-
|
|
116
|
-
expect(search_result.results.first.type).to eq('article')
|
|
117
|
-
end
|
|
118
|
-
end
|
|
137
|
+
describe 'Enumerable' do
|
|
119
138
|
|
|
120
|
-
|
|
139
|
+
let(:search_result) do
|
|
140
|
+
Article.search('title:test')
|
|
141
|
+
end
|
|
121
142
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
143
|
+
it 'allows iteration over results' do
|
|
144
|
+
expect(search_result.results.map(&:_id)).to eq(['1', '2'])
|
|
145
|
+
end
|
|
125
146
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
expect(h._score).not_to be_nil
|
|
129
|
-
expect(h._source.title).not_to be_nil
|
|
147
|
+
it 'allows iteration over records' do
|
|
148
|
+
expect(search_result.records.map(&:id)).to eq([1, 2])
|
|
130
149
|
end
|
|
131
150
|
end
|
|
132
|
-
end
|
|
133
151
|
|
|
134
|
-
|
|
152
|
+
describe '#id' do
|
|
135
153
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
154
|
+
let(:search_result) do
|
|
155
|
+
Article.search('title:test')
|
|
156
|
+
end
|
|
139
157
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
expect(search_result.records.first).to eq(search_result.records[0])
|
|
158
|
+
it 'returns the id' do
|
|
159
|
+
expect(search_result.results.first.id).to eq('1')
|
|
160
|
+
end
|
|
144
161
|
end
|
|
145
162
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
163
|
+
describe '#id' do
|
|
164
|
+
|
|
165
|
+
let(:search_result) do
|
|
166
|
+
Article.search('title:test')
|
|
149
167
|
end
|
|
150
168
|
|
|
151
|
-
|
|
152
|
-
expect(
|
|
169
|
+
it 'returns the type' do
|
|
170
|
+
expect(search_result.results.first.type).to eq('article')
|
|
153
171
|
end
|
|
154
172
|
end
|
|
155
|
-
end
|
|
156
173
|
|
|
157
|
-
|
|
174
|
+
describe '#each_with_hit' do
|
|
158
175
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
from: 1)
|
|
163
|
-
end
|
|
176
|
+
let(:search_result) do
|
|
177
|
+
Article.search('title:test')
|
|
178
|
+
end
|
|
164
179
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
180
|
+
it 'returns the record with the Elasticsearch hit' do
|
|
181
|
+
search_result.records.each_with_hit do |r, h|
|
|
182
|
+
expect(h._score).not_to be_nil
|
|
183
|
+
expect(h._source.title).not_to be_nil
|
|
184
|
+
end
|
|
185
|
+
end
|
|
170
186
|
end
|
|
171
|
-
end
|
|
172
187
|
|
|
173
|
-
|
|
188
|
+
describe 'search results order' do
|
|
174
189
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
Article.where(title: 'destroy').first.destroy
|
|
190
|
+
let(:search_result) do
|
|
191
|
+
Article.search(query: { match: { title: 'code' }}, sort: { clicks: :desc })
|
|
192
|
+
end
|
|
179
193
|
|
|
180
|
-
|
|
181
|
-
|
|
194
|
+
it 'preserves the search results order when accessing a single record' do
|
|
195
|
+
expect(search_result.records[0].clicks).to be(3)
|
|
196
|
+
expect(search_result.records[1].clicks).to be(2)
|
|
197
|
+
expect(search_result.records.first).to eq(search_result.records[0])
|
|
198
|
+
end
|
|
182
199
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
200
|
+
it 'preserves the search results order for the list of records' do
|
|
201
|
+
search_result.records.each_with_hit do |r, h|
|
|
202
|
+
expect(r.id.to_s).to eq(h._id)
|
|
203
|
+
end
|
|
186
204
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
205
|
+
search_result.records.map_with_hit do |r, h|
|
|
206
|
+
expect(r.id.to_s).to eq(h._id)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
191
209
|
end
|
|
192
|
-
end
|
|
193
210
|
|
|
194
|
-
|
|
211
|
+
describe 'a paged collection' do
|
|
195
212
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
213
|
+
let(:search_result) do
|
|
214
|
+
Article.search(query: { match: { title: { query: 'test' } } },
|
|
215
|
+
size: 2,
|
|
216
|
+
from: 1)
|
|
217
|
+
end
|
|
201
218
|
|
|
202
|
-
|
|
219
|
+
it 'applies the paged options to the search' do
|
|
220
|
+
expect(search_result.results.size).to eq(1)
|
|
221
|
+
expect(search_result.results.first.title).to eq('Testing Coding')
|
|
222
|
+
expect(search_result.records.size).to eq(1)
|
|
223
|
+
expect(search_result.records.first.title).to eq('Testing Coding')
|
|
224
|
+
end
|
|
203
225
|
end
|
|
204
226
|
|
|
205
|
-
|
|
206
|
-
Article.search('title:write')
|
|
207
|
-
end
|
|
227
|
+
describe '#destroy' do
|
|
208
228
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
end
|
|
229
|
+
before do
|
|
230
|
+
Article.create!(title: 'destroy', body: '', clicks: 1)
|
|
231
|
+
Article.__elasticsearch__.refresh_index!
|
|
232
|
+
Article.where(title: 'destroy').first.destroy
|
|
214
233
|
|
|
215
|
-
|
|
234
|
+
Article.__elasticsearch__.refresh_index!
|
|
235
|
+
end
|
|
216
236
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
article.title = 'special'
|
|
221
|
-
article.save
|
|
237
|
+
let(:search_result) do
|
|
238
|
+
Article.search('title:test')
|
|
239
|
+
end
|
|
222
240
|
|
|
223
|
-
|
|
241
|
+
it 'removes the document from the index' do
|
|
242
|
+
expect(Article.count).to eq(3)
|
|
243
|
+
expect(search_result.results.size).to eq(2)
|
|
244
|
+
expect(search_result.records.size).to eq(2)
|
|
245
|
+
end
|
|
224
246
|
end
|
|
225
247
|
|
|
226
|
-
|
|
227
|
-
Article.search('title:special')
|
|
228
|
-
end
|
|
248
|
+
describe 'full document updates' do
|
|
229
249
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
250
|
+
before do
|
|
251
|
+
article = Article.create!(title: 'update', body: '', clicks: 1)
|
|
252
|
+
Article.__elasticsearch__.refresh_index!
|
|
253
|
+
article.title = 'Writing'
|
|
254
|
+
article.save
|
|
235
255
|
|
|
236
|
-
|
|
256
|
+
Article.__elasticsearch__.refresh_index!
|
|
257
|
+
end
|
|
237
258
|
|
|
238
|
-
|
|
239
|
-
|
|
259
|
+
let(:search_result) do
|
|
260
|
+
Article.search('title:write')
|
|
261
|
+
end
|
|
240
262
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
263
|
+
it 'applies the update' do
|
|
264
|
+
expect(search_result.results.size).to eq(1)
|
|
265
|
+
expect(search_result.records.size).to eq(1)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
describe 'attribute updates' do
|
|
244
270
|
|
|
271
|
+
before do
|
|
272
|
+
article = Article.create!(title: 'update', body: '', clicks: 1)
|
|
273
|
+
Article.__elasticsearch__.refresh_index!
|
|
245
274
|
article.title = 'special'
|
|
246
275
|
article.save
|
|
276
|
+
|
|
277
|
+
Article.__elasticsearch__.refresh_index!
|
|
247
278
|
end
|
|
248
279
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
280
|
+
let(:search_result) do
|
|
281
|
+
Article.search('title:special')
|
|
282
|
+
end
|
|
252
283
|
|
|
253
|
-
|
|
254
|
-
|
|
284
|
+
it 'applies the update' do
|
|
285
|
+
expect(search_result.results.size).to eq(1)
|
|
286
|
+
expect(search_result.records.size).to eq(1)
|
|
287
|
+
end
|
|
255
288
|
end
|
|
256
289
|
|
|
257
|
-
|
|
258
|
-
expect(search_result.results.size).to eq(1)
|
|
259
|
-
expect(search_result.records.size).to eq(1)
|
|
260
|
-
end
|
|
261
|
-
end
|
|
290
|
+
describe '#save' do
|
|
262
291
|
|
|
263
|
-
|
|
292
|
+
before do
|
|
293
|
+
article = Article.create!(title: 'save', body: '', clicks: 1)
|
|
264
294
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
295
|
+
ActiveRecord::Base.transaction do
|
|
296
|
+
article.body = 'dummy'
|
|
297
|
+
article.save
|
|
268
298
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
end
|
|
273
|
-
end
|
|
299
|
+
article.title = 'special'
|
|
300
|
+
article.save
|
|
301
|
+
end
|
|
274
302
|
|
|
275
|
-
|
|
303
|
+
article.__elasticsearch__.update_document
|
|
304
|
+
Article.__elasticsearch__.refresh_index!
|
|
305
|
+
end
|
|
276
306
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
307
|
+
let(:search_result) do
|
|
308
|
+
Article.search('body:dummy')
|
|
309
|
+
end
|
|
280
310
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
311
|
+
it 'applies the save' do
|
|
312
|
+
expect(search_result.results.size).to eq(1)
|
|
313
|
+
expect(search_result.records.size).to eq(1)
|
|
314
|
+
end
|
|
285
315
|
end
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
describe 'ordering of SQL queries' do
|
|
289
316
|
|
|
290
|
-
|
|
317
|
+
describe 'a DSL search' do
|
|
291
318
|
|
|
292
319
|
let(:search_result) do
|
|
293
|
-
Article.search
|
|
320
|
+
Article.search(query: { match: { title: { query: 'test' } } })
|
|
294
321
|
end
|
|
295
322
|
|
|
296
|
-
it '
|
|
297
|
-
expect(search_result.
|
|
298
|
-
expect(search_result.records.
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
it 'allows the SQL query to be ordered independent of the Elasticsearch results order', if: active_record_at_least_4? do
|
|
302
|
-
expect(search_result.records.order(title: :desc).first.title).to eq('Testing Coding')
|
|
303
|
-
expect(search_result.records.order(title: :desc)[0].title).to eq('Testing Coding')
|
|
323
|
+
it 'returns the results' do
|
|
324
|
+
expect(search_result.results.size).to eq(2)
|
|
325
|
+
expect(search_result.records.size).to eq(2)
|
|
304
326
|
end
|
|
305
327
|
end
|
|
306
328
|
|
|
307
|
-
|
|
329
|
+
describe 'chaining SQL queries on response.records' do
|
|
308
330
|
|
|
309
331
|
let(:search_result) do
|
|
310
|
-
Article.search
|
|
332
|
+
Article.search(query: { match: { title: { query: 'test' } } })
|
|
311
333
|
end
|
|
312
334
|
|
|
313
|
-
it '
|
|
314
|
-
expect(search_result.records.
|
|
315
|
-
expect(search_result.records.
|
|
335
|
+
it 'executes the SQL request with the chained query criteria' do
|
|
336
|
+
expect(search_result.records.size).to eq(2)
|
|
337
|
+
expect(search_result.records.where(title: 'Test').size).to eq(1)
|
|
338
|
+
expect(search_result.records.where(title: 'Test').first.title).to eq('Test')
|
|
316
339
|
end
|
|
317
340
|
end
|
|
318
|
-
end
|
|
319
341
|
|
|
320
|
-
|
|
342
|
+
describe 'ordering of SQL queries' do
|
|
343
|
+
|
|
344
|
+
context 'when order is called on the ActiveRecord query' do
|
|
345
|
+
|
|
346
|
+
let(:search_result) do
|
|
347
|
+
Article.search query: { match: { title: { query: 'test' } } }
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it 'allows the SQL query to be ordered independent of the Elasticsearch results order', unless: active_record_at_least_4? do
|
|
351
|
+
expect(search_result.records.order('title DESC').first.title).to eq('Testing Coding')
|
|
352
|
+
expect(search_result.records.order('title DESC')[0].title).to eq('Testing Coding')
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it 'allows the SQL query to be ordered independent of the Elasticsearch results order', if: active_record_at_least_4? do
|
|
356
|
+
expect(search_result.records.order(title: :desc).first.title).to eq('Testing Coding')
|
|
357
|
+
expect(search_result.records.order(title: :desc)[0].title).to eq('Testing Coding')
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
context 'when more methods are chained on the ActiveRecord query' do
|
|
362
|
+
|
|
363
|
+
let(:search_result) do
|
|
364
|
+
Article.search query: {match: {title: {query: 'test'}}}
|
|
365
|
+
end
|
|
321
366
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
},
|
|
328
|
-
suggest: { text: 'tezt', title: { term: { field: 'title', suggest_mode: 'always' } } })
|
|
367
|
+
it 'allows the SQL query to be ordered independent of the Elasticsearch results order', if: active_record_at_least_4? do
|
|
368
|
+
expect(search_result.records.distinct.order(title: :desc).first.title).to eq('Testing Coding')
|
|
369
|
+
expect(search_result.records.distinct.order(title: :desc)[0].title).to eq('Testing Coding')
|
|
370
|
+
end
|
|
371
|
+
end
|
|
329
372
|
end
|
|
330
373
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
374
|
+
describe 'access to the response via methods' do
|
|
375
|
+
|
|
376
|
+
let(:search_result) do
|
|
377
|
+
Article.search(query: { match: { title: { query: 'test' } } },
|
|
378
|
+
aggregations: {
|
|
379
|
+
dates: { date_histogram: { field: 'created_at', interval: 'hour' } },
|
|
380
|
+
clicks: { global: {}, aggregations: { min: { min: { field: 'clicks' } } } }
|
|
381
|
+
},
|
|
382
|
+
suggest: { text: 'tezt', title: { term: { field: 'title', suggest_mode: 'always' } } })
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
it 'allows document keys to be access via methods' do
|
|
386
|
+
expect(search_result.aggregations.dates.buckets.first.doc_count).to eq(2)
|
|
387
|
+
expect(search_result.aggregations.clicks.doc_count).to eq(6)
|
|
388
|
+
expect(search_result.aggregations.clicks.min.value).to eq(1.0)
|
|
389
|
+
expect(search_result.aggregations.clicks.max).to be_nil
|
|
390
|
+
expect(search_result.suggestions.title.first.options.size).to eq(1)
|
|
391
|
+
expect(search_result.suggestions.terms).to eq(['test'])
|
|
392
|
+
end
|
|
338
393
|
end
|
|
339
394
|
end
|
|
340
395
|
end
|