elasticsearch-model 0.1.9 → 7.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -2
  3. data/Gemfile +22 -0
  4. data/LICENSE.txt +199 -10
  5. data/README.md +96 -43
  6. data/Rakefile +49 -35
  7. data/elasticsearch-model.gemspec +53 -41
  8. data/examples/activerecord_article.rb +18 -1
  9. data/examples/activerecord_associations.rb +86 -17
  10. data/examples/activerecord_custom_analyzer.rb +152 -0
  11. data/examples/activerecord_mapping_completion.rb +33 -16
  12. data/examples/activerecord_mapping_edge_ngram.rb +118 -0
  13. data/examples/couchbase_article.rb +17 -0
  14. data/examples/datamapper_article.rb +28 -1
  15. data/examples/mongoid_article.rb +17 -0
  16. data/examples/ohm_article.rb +17 -0
  17. data/examples/riak_article.rb +17 -0
  18. data/gemfiles/3.0.gemfile +23 -1
  19. data/gemfiles/4.0.gemfile +25 -1
  20. data/gemfiles/5.0.gemfile +35 -0
  21. data/gemfiles/6.0.gemfile +36 -0
  22. data/lib/elasticsearch/model/adapter.rb +17 -0
  23. data/lib/elasticsearch/model/adapters/active_record.rb +31 -27
  24. data/lib/elasticsearch/model/adapters/default.rb +17 -0
  25. data/lib/elasticsearch/model/adapters/mongoid.rb +27 -3
  26. data/lib/elasticsearch/model/adapters/multiple.rb +29 -4
  27. data/lib/elasticsearch/model/callbacks.rb +17 -0
  28. data/lib/elasticsearch/model/client.rb +17 -0
  29. data/lib/elasticsearch/model/ext/active_record.rb +17 -0
  30. data/lib/elasticsearch/model/hash_wrapper.rb +32 -0
  31. data/lib/elasticsearch/model/importing.rb +61 -17
  32. data/lib/elasticsearch/model/indexing.rb +87 -49
  33. data/lib/elasticsearch/model/multimodel.rb +17 -0
  34. data/lib/elasticsearch/model/naming.rb +33 -2
  35. data/lib/elasticsearch/model/proxy.rb +61 -18
  36. data/lib/elasticsearch/model/response/aggregations.rb +55 -0
  37. data/lib/elasticsearch/model/response/base.rb +25 -3
  38. data/lib/elasticsearch/model/response/pagination/kaminari.rb +126 -0
  39. data/lib/elasticsearch/model/response/pagination/will_paginate.rb +112 -0
  40. data/lib/elasticsearch/model/response/pagination.rb +19 -192
  41. data/lib/elasticsearch/model/response/records.rb +17 -1
  42. data/lib/elasticsearch/model/response/result.rb +19 -2
  43. data/lib/elasticsearch/model/response/results.rb +17 -0
  44. data/lib/elasticsearch/model/response/suggestions.rb +20 -1
  45. data/lib/elasticsearch/model/response.rb +28 -10
  46. data/lib/elasticsearch/model/searching.rb +17 -0
  47. data/lib/elasticsearch/model/serializing.rb +17 -0
  48. data/lib/elasticsearch/model/version.rb +18 -1
  49. data/lib/elasticsearch/model.rb +36 -39
  50. data/spec/elasticsearch/model/adapter_spec.rb +136 -0
  51. data/spec/elasticsearch/model/adapters/active_record/associations_spec.rb +351 -0
  52. data/spec/elasticsearch/model/adapters/active_record/basic_spec.rb +395 -0
  53. data/spec/elasticsearch/model/adapters/active_record/dynamic_index_name_spec.rb +35 -0
  54. data/spec/elasticsearch/model/adapters/active_record/import_spec.rb +193 -0
  55. data/spec/elasticsearch/model/adapters/active_record/multi_model_spec.rb +127 -0
  56. data/spec/elasticsearch/model/adapters/active_record/namespaced_model_spec.rb +55 -0
  57. data/spec/elasticsearch/model/adapters/active_record/pagination_spec.rb +332 -0
  58. data/spec/elasticsearch/model/adapters/active_record/parent_child_spec.rb +92 -0
  59. data/spec/elasticsearch/model/adapters/active_record/serialization_spec.rb +78 -0
  60. data/spec/elasticsearch/model/adapters/active_record_spec.rb +224 -0
  61. data/spec/elasticsearch/model/adapters/default_spec.rb +58 -0
  62. data/spec/elasticsearch/model/adapters/mongoid/basic_spec.rb +284 -0
  63. data/spec/elasticsearch/model/adapters/mongoid/multi_model_spec.rb +83 -0
  64. data/spec/elasticsearch/model/adapters/mongoid_spec.rb +252 -0
  65. data/spec/elasticsearch/model/adapters/multiple_spec.rb +142 -0
  66. data/spec/elasticsearch/model/callbacks_spec.rb +50 -0
  67. data/spec/elasticsearch/model/client_spec.rb +83 -0
  68. data/spec/elasticsearch/model/hash_wrapper_spec.rb +29 -0
  69. data/spec/elasticsearch/model/importing_spec.rb +243 -0
  70. data/spec/elasticsearch/model/indexing_spec.rb +1014 -0
  71. data/spec/elasticsearch/model/module_spec.rb +94 -0
  72. data/spec/elasticsearch/model/multimodel_spec.rb +72 -0
  73. data/spec/elasticsearch/model/naming_spec.rb +203 -0
  74. data/spec/elasticsearch/model/proxy_spec.rb +124 -0
  75. data/spec/elasticsearch/model/response/aggregations_spec.rb +83 -0
  76. data/spec/elasticsearch/model/response/base_spec.rb +107 -0
  77. data/spec/elasticsearch/model/response/pagination/kaminari_spec.rb +472 -0
  78. data/spec/elasticsearch/model/response/pagination/will_paginate_spec.rb +279 -0
  79. data/spec/elasticsearch/model/response/records_spec.rb +135 -0
  80. data/spec/elasticsearch/model/response/response_spec.rb +148 -0
  81. data/spec/elasticsearch/model/response/result_spec.rb +139 -0
  82. data/spec/elasticsearch/model/response/results_spec.rb +73 -0
  83. data/spec/elasticsearch/model/searching_search_request_spec.rb +129 -0
  84. data/spec/elasticsearch/model/searching_spec.rb +66 -0
  85. data/spec/elasticsearch/model/serializing_spec.rb +39 -0
  86. data/spec/spec_helper.rb +193 -0
  87. data/spec/support/app/answer.rb +50 -0
  88. data/spec/support/app/article.rb +39 -0
  89. data/spec/support/app/article_for_pagination.rb +29 -0
  90. data/spec/support/app/article_no_type.rb +37 -0
  91. data/spec/support/app/article_with_custom_serialization.rb +30 -0
  92. data/spec/support/app/article_with_dynamic_index_name.rb +32 -0
  93. data/spec/support/app/author.rb +26 -0
  94. data/spec/support/app/authorship.rb +21 -0
  95. data/spec/support/app/category.rb +20 -0
  96. data/spec/support/app/comment.rb +20 -0
  97. data/spec/support/app/episode.rb +28 -0
  98. data/spec/support/app/image.rb +36 -0
  99. data/spec/support/app/import_article.rb +29 -0
  100. data/spec/support/app/mongoid_article.rb +38 -0
  101. data/spec/support/app/namespaced_book.rb +27 -0
  102. data/spec/support/app/parent_and_child_searchable.rb +41 -0
  103. data/spec/support/app/post.rb +31 -0
  104. data/spec/support/app/question.rb +44 -0
  105. data/spec/support/app/searchable.rb +65 -0
  106. data/spec/support/app/series.rb +28 -0
  107. data/spec/support/app.rb +46 -0
  108. data/spec/support/model.json +1 -0
  109. data/{test → spec}/support/model.yml +0 -0
  110. metadata +175 -121
  111. data/test/integration/active_record_associations_parent_child.rb +0 -139
  112. data/test/integration/active_record_associations_test.rb +0 -326
  113. data/test/integration/active_record_basic_test.rb +0 -234
  114. data/test/integration/active_record_custom_serialization_test.rb +0 -62
  115. data/test/integration/active_record_import_test.rb +0 -109
  116. data/test/integration/active_record_namespaced_model_test.rb +0 -49
  117. data/test/integration/active_record_pagination_test.rb +0 -145
  118. data/test/integration/dynamic_index_name_test.rb +0 -47
  119. data/test/integration/mongoid_basic_test.rb +0 -177
  120. data/test/integration/multiple_models_test.rb +0 -172
  121. data/test/support/model.json +0 -1
  122. data/test/test_helper.rb +0 -93
  123. data/test/unit/adapter_active_record_test.rb +0 -157
  124. data/test/unit/adapter_default_test.rb +0 -41
  125. data/test/unit/adapter_mongoid_test.rb +0 -104
  126. data/test/unit/adapter_multiple_test.rb +0 -106
  127. data/test/unit/adapter_test.rb +0 -69
  128. data/test/unit/callbacks_test.rb +0 -31
  129. data/test/unit/client_test.rb +0 -27
  130. data/test/unit/importing_test.rb +0 -203
  131. data/test/unit/indexing_test.rb +0 -650
  132. data/test/unit/module_test.rb +0 -57
  133. data/test/unit/multimodel_test.rb +0 -38
  134. data/test/unit/naming_test.rb +0 -103
  135. data/test/unit/proxy_test.rb +0 -100
  136. data/test/unit/response_base_test.rb +0 -40
  137. data/test/unit/response_pagination_kaminari_test.rb +0 -433
  138. data/test/unit/response_pagination_will_paginate_test.rb +0 -398
  139. data/test/unit/response_records_test.rb +0 -91
  140. data/test/unit/response_result_test.rb +0 -90
  141. data/test/unit/response_results_test.rb +0 -31
  142. data/test/unit/response_test.rb +0 -104
  143. data/test/unit/searching_search_request_test.rb +0 -78
  144. data/test/unit/searching_test.rb +0 -41
  145. data/test/unit/serializing_test.rb +0 -17
@@ -1,109 +0,0 @@
1
- require 'test_helper'
2
- require 'active_record'
3
-
4
- module Elasticsearch
5
- module Model
6
- class ActiveRecordImportIntegrationTest < Elasticsearch::Test::IntegrationTestCase
7
- context "ActiveRecord importing" do
8
- setup do
9
- ActiveRecord::Schema.define(:version => 1) do
10
- create_table :import_articles do |t|
11
- t.string :title
12
- t.integer :views
13
- t.string :numeric # For the sake of invalid data sent to Elasticsearch
14
- t.datetime :created_at, :default => 'NOW()'
15
- end
16
- end
17
-
18
- class ::ImportArticle < ActiveRecord::Base
19
- include Elasticsearch::Model
20
-
21
- scope :popular, -> { where('views >= 50') }
22
-
23
- mapping do
24
- indexes :title, type: 'string'
25
- indexes :views, type: 'integer'
26
- indexes :numeric, type: 'integer'
27
- indexes :created_at, type: 'date'
28
- end
29
- end
30
-
31
- ImportArticle.delete_all
32
- ImportArticle.__elasticsearch__.create_index! force: true
33
- ImportArticle.__elasticsearch__.client.cluster.health wait_for_status: 'yellow'
34
-
35
- 100.times { |i| ImportArticle.create! title: "Test #{i}", views: i }
36
- end
37
-
38
- should "import all the documents" do
39
- assert_equal 100, ImportArticle.count
40
-
41
- ImportArticle.__elasticsearch__.refresh_index!
42
- assert_equal 0, ImportArticle.search('*').results.total
43
-
44
- batches = 0
45
- errors = ImportArticle.import(batch_size: 10) do |response|
46
- batches += 1
47
- end
48
-
49
- assert_equal 0, errors
50
- assert_equal 10, batches
51
-
52
- ImportArticle.__elasticsearch__.refresh_index!
53
- assert_equal 100, ImportArticle.search('*').results.total
54
- end
55
-
56
- should "import only documents from a specific scope" do
57
- assert_equal 100, ImportArticle.count
58
-
59
- assert_equal 0, ImportArticle.import(scope: 'popular')
60
-
61
- ImportArticle.__elasticsearch__.refresh_index!
62
- assert_equal 50, ImportArticle.search('*').results.total
63
- end
64
-
65
- should "import only documents from a specific query" do
66
- assert_equal 100, ImportArticle.count
67
-
68
- assert_equal 0, ImportArticle.import(query: -> { where('views >= 30') })
69
-
70
- ImportArticle.__elasticsearch__.refresh_index!
71
- assert_equal 70, ImportArticle.search('*').results.total
72
- end
73
-
74
- should "report and not store/index invalid documents" do
75
- ImportArticle.create! title: "Test INVALID", numeric: "INVALID"
76
-
77
- assert_equal 101, ImportArticle.count
78
-
79
- ImportArticle.__elasticsearch__.refresh_index!
80
- assert_equal 0, ImportArticle.search('*').results.total
81
-
82
- batches = 0
83
- errors = ImportArticle.__elasticsearch__.import(batch_size: 10) do |response|
84
- batches += 1
85
- end
86
-
87
- assert_equal 1, errors
88
- assert_equal 11, batches
89
-
90
- ImportArticle.__elasticsearch__.refresh_index!
91
- assert_equal 100, ImportArticle.search('*').results.total
92
- end
93
-
94
- should "transform documents with the option" do
95
- assert_equal 100, ImportArticle.count
96
-
97
- assert_equal 0, ImportArticle.import( transform: ->(a) {{ index: { data: { name: a.title, foo: 'BAR' } }}} )
98
-
99
- ImportArticle.__elasticsearch__.refresh_index!
100
- assert_contains ImportArticle.search('*').results.first._source.keys, 'name'
101
- assert_contains ImportArticle.search('*').results.first._source.keys, 'foo'
102
- assert_equal 100, ImportArticle.search('test').results.total
103
- assert_equal 100, ImportArticle.search('bar').results.total
104
- end
105
- end
106
-
107
- end
108
- end
109
- end
@@ -1,49 +0,0 @@
1
- require 'test_helper'
2
- require 'active_record'
3
-
4
- module Elasticsearch
5
- module Model
6
- class ActiveRecordNamespacedModelIntegrationTest < Elasticsearch::Test::IntegrationTestCase
7
- context "Namespaced ActiveRecord model integration" do
8
- setup do
9
- ActiveRecord::Schema.define(:version => 1) do
10
- create_table :articles do |t|
11
- t.string :title
12
- end
13
- end
14
-
15
- module ::MyNamespace
16
- class Article < ActiveRecord::Base
17
- include Elasticsearch::Model
18
- include Elasticsearch::Model::Callbacks
19
-
20
- mapping { indexes :title }
21
- end
22
- end
23
-
24
- MyNamespace::Article.delete_all
25
- MyNamespace::Article.__elasticsearch__.create_index! force: true
26
-
27
- MyNamespace::Article.create! title: 'Test'
28
-
29
- MyNamespace::Article.__elasticsearch__.refresh_index!
30
- end
31
-
32
- should "have proper index name and document type" do
33
- assert_equal "my_namespace-articles", MyNamespace::Article.index_name
34
- assert_equal "article", MyNamespace::Article.document_type
35
- end
36
-
37
- should "save document into index on save and find it" do
38
- response = MyNamespace::Article.search 'title:test'
39
-
40
- assert response.any?, "No results returned: #{response.inspect}"
41
- assert_equal 1, response.size
42
-
43
- assert_equal 'Test', response.results.first.title
44
- end
45
- end
46
-
47
- end
48
- end
49
- end
@@ -1,145 +0,0 @@
1
- require 'test_helper'
2
- require 'active_record'
3
-
4
- module Elasticsearch
5
- module Model
6
- class ActiveRecordPaginationTest < Elasticsearch::Test::IntegrationTestCase
7
- context "ActiveRecord pagination" do
8
- setup do
9
- class ::ArticleForPagination < ActiveRecord::Base
10
- include Elasticsearch::Model
11
-
12
- scope :published, -> { where(published: true) }
13
-
14
- settings index: { number_of_shards: 1, number_of_replicas: 0 } do
15
- mapping do
16
- indexes :title, type: 'string', analyzer: 'snowball'
17
- indexes :created_at, type: 'date'
18
- end
19
- end
20
- end
21
-
22
- ActiveRecord::Schema.define(:version => 1) do
23
- create_table ::ArticleForPagination.table_name do |t|
24
- t.string :title
25
- t.datetime :created_at, :default => 'NOW()'
26
- t.boolean :published
27
- end
28
- end
29
-
30
- Kaminari::Hooks.init
31
-
32
- ArticleForPagination.delete_all
33
- ArticleForPagination.__elasticsearch__.create_index! force: true
34
-
35
- 68.times do |i|
36
- ::ArticleForPagination.create! title: "Test #{i}", published: (i % 2 == 0)
37
- end
38
-
39
- ArticleForPagination.import
40
- ArticleForPagination.__elasticsearch__.refresh_index!
41
- end
42
-
43
- should "be on the first page by default" do
44
- records = ArticleForPagination.search('title:test').page(1).records
45
-
46
- assert_equal 25, records.size
47
- assert_equal 1, records.current_page
48
- assert_equal nil, records.prev_page
49
- assert_equal 2, records.next_page
50
- assert_equal 3, records.total_pages
51
-
52
- assert records.first_page?, "Should be the first page"
53
- assert ! records.last_page?, "Should NOT be the last page"
54
- assert ! records.out_of_range?, "Should NOT be out of range"
55
- end
56
-
57
- should "load next page" do
58
- records = ArticleForPagination.search('title:test').page(2).records
59
-
60
- assert_equal 25, records.size
61
- assert_equal 2, records.current_page
62
- assert_equal 1, records.prev_page
63
- assert_equal 3, records.next_page
64
- assert_equal 3, records.total_pages
65
-
66
- assert ! records.first_page?, "Should NOT be the first page"
67
- assert ! records.last_page?, "Should NOT be the last page"
68
- assert ! records.out_of_range?, "Should NOT be out of range"
69
- end
70
-
71
- should "load last page" do
72
- records = ArticleForPagination.search('title:test').page(3).records
73
-
74
- assert_equal 18, records.size
75
- assert_equal 3, records.current_page
76
- assert_equal 2, records.prev_page
77
- assert_equal nil, records.next_page
78
- assert_equal 3, records.total_pages
79
-
80
- assert ! records.first_page?, "Should NOT be the first page"
81
- assert records.last_page?, "Should be the last page"
82
- assert ! records.out_of_range?, "Should NOT be out of range"
83
- end
84
-
85
- should "not load invalid page" do
86
- records = ArticleForPagination.search('title:test').page(6).records
87
-
88
- assert_equal 0, records.size
89
- assert_equal 6, records.current_page
90
- assert_equal 5, records.prev_page
91
- assert_equal nil, records.next_page
92
- assert_equal 3, records.total_pages
93
-
94
- assert ! records.first_page?, "Should NOT be the first page"
95
- assert records.last_page?, "Should be the last page"
96
- assert records.out_of_range?, "Should be out of range"
97
- end
98
-
99
- should "be combined with scopes" do
100
- records = ArticleForPagination.search('title:test').page(2).records.published
101
- assert records.all? { |r| r.published? }
102
- assert_equal 12, records.size
103
- end
104
-
105
- should "respect sort" do
106
- search = ArticleForPagination.search({ query: { match: { title: 'test' } }, sort: [ { id: 'desc' } ] })
107
-
108
- records = search.page(2).records
109
- assert_equal 43, records.first.id # 68 - 25 = 42
110
-
111
- records = search.page(3).records
112
- assert_equal 18, records.first.id # 68 - (2 * 25) = 18
113
-
114
- records = search.page(2).per(5).records
115
- assert_equal 63, records.first.id # 68 - 5 = 63
116
- end
117
-
118
- should "set the limit per request" do
119
- records = ArticleForPagination.search('title:test').limit(50).page(2).records
120
-
121
- assert_equal 18, records.size
122
- assert_equal 2, records.current_page
123
- assert_equal 1, records.prev_page
124
- assert_equal nil, records.next_page
125
- assert_equal 2, records.total_pages
126
-
127
- assert records.last_page?, "Should be the last page"
128
- end
129
-
130
- context "with specific model settings" do
131
- teardown do
132
- ArticleForPagination.instance_variable_set(:@_default_per_page, nil)
133
- end
134
-
135
- should "respect paginates_per" do
136
- ArticleForPagination.paginates_per 50
137
-
138
- assert_equal 50, ArticleForPagination.search('*').page(1).records.size
139
- end
140
- end
141
- end
142
-
143
- end
144
- end
145
- end
@@ -1,47 +0,0 @@
1
- require 'test_helper'
2
- require 'active_record'
3
-
4
- module Elasticsearch
5
- module Model
6
- class DynamicIndexNameTest < Elasticsearch::Test::IntegrationTestCase
7
- context "Dynamic index name" do
8
- setup do
9
- class ::ArticleWithDynamicIndexName < ActiveRecord::Base
10
- include Elasticsearch::Model
11
- include Elasticsearch::Model::Callbacks
12
-
13
- def self.counter=(value)
14
- @counter = 0
15
- end
16
-
17
- def self.counter
18
- (@counter ||= 0) && @counter += 1
19
- end
20
-
21
- mapping { indexes :title }
22
- index_name { "articles-#{counter}" }
23
- end
24
-
25
- ::ActiveRecord::Schema.define(:version => 1) do
26
- create_table ::ArticleWithDynamicIndexName.table_name do |t|
27
- t.string :title
28
- end
29
- end
30
-
31
- ::ArticleWithDynamicIndexName.counter = 0
32
- end
33
-
34
- should 'evaluate the index_name value' do
35
- assert_equal ArticleWithDynamicIndexName.index_name, "articles-1"
36
- end
37
-
38
- should 're-evaluate the index_name value each time' do
39
- assert_equal ArticleWithDynamicIndexName.index_name, "articles-1"
40
- assert_equal ArticleWithDynamicIndexName.index_name, "articles-2"
41
- assert_equal ArticleWithDynamicIndexName.index_name, "articles-3"
42
- end
43
- end
44
-
45
- end
46
- end
47
- end
@@ -1,177 +0,0 @@
1
- require 'test_helper'
2
-
3
- Mongo.setup!
4
-
5
- if Mongo.available?
6
- Mongo.connect_to 'mongoid_articles'
7
-
8
- module Elasticsearch
9
- module Model
10
- class MongoidBasicIntegrationTest < Elasticsearch::Test::IntegrationTestCase
11
-
12
- class ::MongoidArticle
13
- include Mongoid::Document
14
- include Elasticsearch::Model
15
- include Elasticsearch::Model::Callbacks
16
-
17
- field :id, type: String
18
- field :title, type: String
19
- attr_accessible :title if respond_to? :attr_accessible
20
-
21
- settings index: { number_of_shards: 1, number_of_replicas: 0 } do
22
- mapping do
23
- indexes :title, type: 'string', analyzer: 'snowball'
24
- indexes :created_at, type: 'date'
25
- end
26
- end
27
-
28
- def as_indexed_json(options={})
29
- as_json(except: [:id, :_id])
30
- end
31
- end
32
-
33
- context "Mongoid integration" do
34
- setup do
35
- Elasticsearch::Model::Adapter.register \
36
- Elasticsearch::Model::Adapter::Mongoid,
37
- lambda { |klass| !!defined?(::Mongoid::Document) && klass.respond_to?(:ancestors) && klass.ancestors.include?(::Mongoid::Document) }
38
-
39
- MongoidArticle.__elasticsearch__.create_index! force: true
40
-
41
- MongoidArticle.delete_all
42
-
43
- MongoidArticle.create! title: 'Test'
44
- MongoidArticle.create! title: 'Testing Coding'
45
- MongoidArticle.create! title: 'Coding'
46
-
47
- MongoidArticle.__elasticsearch__.refresh_index!
48
- MongoidArticle.__elasticsearch__.client.cluster.health wait_for_status: 'yellow'
49
- end
50
-
51
- should "index and find a document" do
52
- response = MongoidArticle.search('title:test')
53
-
54
- assert response.any?
55
-
56
- assert_equal 2, response.results.size
57
- assert_equal 2, response.records.size
58
-
59
- assert_instance_of Elasticsearch::Model::Response::Result, response.results.first
60
- assert_instance_of MongoidArticle, response.records.first
61
-
62
- assert_equal 'Test', response.results.first.title
63
- assert_equal 'Test', response.records.first.title
64
- end
65
-
66
- should "iterate over results" do
67
- response = MongoidArticle.search('title:test')
68
-
69
- assert_equal ['Test', 'Testing Coding'], response.results.map(&:title)
70
- assert_equal ['Test', 'Testing Coding'], response.records.map(&:title)
71
- end
72
-
73
- should "access results from records" do
74
- response = MongoidArticle.search('title:test')
75
-
76
- response.records.each_with_hit do |r, h|
77
- assert_not_nil h._score
78
- assert_not_nil h._source.title
79
- end
80
- end
81
-
82
- should "preserve the search results order for records" do
83
- response = MongoidArticle.search('title:code')
84
-
85
- response.records.each_with_hit do |r, h|
86
- assert_equal h._id, r.id.to_s
87
- end
88
-
89
- response.records.map_with_hit do |r, h|
90
- assert_equal h._id, r.id.to_s
91
- end
92
- end
93
-
94
- should "remove document from index on destroy" do
95
- article = MongoidArticle.first
96
-
97
- article.destroy
98
- assert_equal 2, MongoidArticle.count
99
-
100
- MongoidArticle.__elasticsearch__.refresh_index!
101
-
102
- response = MongoidArticle.search 'title:test'
103
-
104
- assert_equal 1, response.results.size
105
- assert_equal 1, response.records.size
106
- end
107
-
108
- should "index updates to the document" do
109
- article = MongoidArticle.first
110
-
111
- article.title = 'Writing'
112
- article.save
113
-
114
- MongoidArticle.__elasticsearch__.refresh_index!
115
-
116
- response = MongoidArticle.search 'title:write'
117
-
118
- assert_equal 1, response.results.size
119
- assert_equal 1, response.records.size
120
- end
121
-
122
- should "return results for a DSL search" do
123
- response = MongoidArticle.search query: { match: { title: { query: 'test' } } }
124
-
125
- assert_equal 2, response.results.size
126
- assert_equal 2, response.records.size
127
- end
128
-
129
- should "return a paged collection" do
130
- response = MongoidArticle.search query: { match: { title: { query: 'test' } } },
131
- size: 2,
132
- from: 1
133
-
134
- assert_equal 1, response.results.size
135
- assert_equal 1, response.records.size
136
-
137
- assert_equal 'Testing Coding', response.results.first.title
138
- assert_equal 'Testing Coding', response.records.first.title
139
- end
140
-
141
-
142
- context "importing" do
143
- setup do
144
- MongoidArticle.delete_all
145
- 97.times { |i| MongoidArticle.create! title: "Test #{i}" }
146
- MongoidArticle.__elasticsearch__.create_index! force: true
147
- MongoidArticle.__elasticsearch__.client.cluster.health wait_for_status: 'yellow'
148
- end
149
-
150
- should "import all the documents" do
151
- assert_equal 97, MongoidArticle.count
152
-
153
- MongoidArticle.__elasticsearch__.refresh_index!
154
- assert_equal 0, MongoidArticle.search('*').results.total
155
-
156
- batches = 0
157
- errors = MongoidArticle.import(batch_size: 10) do |response|
158
- batches += 1
159
- end
160
-
161
- assert_equal 0, errors
162
- assert_equal 10, batches
163
-
164
- MongoidArticle.__elasticsearch__.refresh_index!
165
- assert_equal 97, MongoidArticle.search('*').results.total
166
-
167
- response = MongoidArticle.search('test')
168
- assert response.results.any?, "Search has not returned results: #{response.to_a}"
169
- end
170
- end
171
- end
172
-
173
- end
174
- end
175
- end
176
-
177
- end
@@ -1,172 +0,0 @@
1
- require 'test_helper'
2
- require 'active_record'
3
-
4
- Mongo.setup!
5
-
6
- module Elasticsearch
7
- module Model
8
- class MultipleModelsIntegration < Elasticsearch::Test::IntegrationTestCase
9
- context "Multiple models" do
10
- setup do
11
- ActiveRecord::Schema.define(:version => 1) do
12
- create_table :episodes do |t|
13
- t.string :name
14
- t.datetime :created_at, :default => 'NOW()'
15
- end
16
-
17
- create_table :series do |t|
18
- t.string :name
19
- t.datetime :created_at, :default => 'NOW()'
20
- end
21
- end
22
-
23
- module ::NameSearch
24
- extend ActiveSupport::Concern
25
-
26
- included do
27
- include Elasticsearch::Model
28
- include Elasticsearch::Model::Callbacks
29
-
30
- settings index: {number_of_shards: 1, number_of_replicas: 0} do
31
- mapping do
32
- indexes :name, type: 'string', analyzer: 'snowball'
33
- indexes :created_at, type: 'date'
34
- end
35
- end
36
- end
37
- end
38
-
39
- class ::Episode < ActiveRecord::Base
40
- include NameSearch
41
- end
42
-
43
- class ::Series < ActiveRecord::Base
44
- include NameSearch
45
- end
46
-
47
- [::Episode, ::Series].each do |model|
48
- model.delete_all
49
- model.__elasticsearch__.create_index! force: true
50
- model.create name: "The #{model.name}"
51
- model.create name: "A great #{model.name}"
52
- model.create name: "The greatest #{model.name}"
53
- model.__elasticsearch__.refresh_index!
54
- end
55
-
56
- end
57
-
58
- should "find matching documents across multiple models" do
59
- response = Elasticsearch::Model.search(%q<"The greatest Episode"^2 OR "The greatest Series">, [Series, Episode])
60
-
61
- assert response.any?, "Response should not be empty: #{response.to_a.inspect}"
62
-
63
- assert_equal 2, response.results.size
64
- assert_equal 2, response.records.size
65
-
66
- assert_instance_of Elasticsearch::Model::Response::Result, response.results.first
67
- assert_instance_of Episode, response.records.first
68
- assert_instance_of Series, response.records.last
69
-
70
- assert_equal 'The greatest Episode', response.results[0].name
71
- assert_equal 'The greatest Episode', response.records[0].name
72
-
73
- assert_equal 'The greatest Series', response.results[1].name
74
- assert_equal 'The greatest Series', response.records[1].name
75
- end
76
-
77
- should "provide access to results" do
78
- response = Elasticsearch::Model.search(%q<"A great Episode"^2 OR "A great Series">, [Series, Episode])
79
-
80
- assert_equal 'A great Episode', response.results[0].name
81
- assert_equal true, response.results[0].name?
82
- assert_equal false, response.results[0].boo?
83
-
84
- assert_equal 'A great Series', response.results[1].name
85
- assert_equal true, response.results[1].name?
86
- assert_equal false, response.results[1].boo?
87
- end
88
-
89
- should "only retrieve records for existing results" do
90
- ::Series.find_by_name("The greatest Series").delete
91
- ::Series.__elasticsearch__.refresh_index!
92
- response = Elasticsearch::Model.search(%q<"The greatest Episode"^2 OR "The greatest Series">, [Series, Episode])
93
-
94
- assert response.any?, "Response should not be empty: #{response.to_a.inspect}"
95
-
96
- assert_equal 2, response.results.size
97
- assert_equal 1, response.records.size
98
-
99
- assert_instance_of Elasticsearch::Model::Response::Result, response.results.first
100
- assert_instance_of Episode, response.records.first
101
-
102
- assert_equal 'The greatest Episode', response.results[0].name
103
- assert_equal 'The greatest Episode', response.records[0].name
104
- end
105
-
106
- should "paginate the results" do
107
- response = Elasticsearch::Model.search('series OR episode', [Series, Episode])
108
-
109
- assert_equal 3, response.page(1).per(3).results.size
110
- assert_equal 3, response.page(2).per(3).results.size
111
- assert_equal 0, response.page(3).per(3).results.size
112
- end
113
-
114
- if Mongo.available?
115
- Mongo.connect_to 'mongoid_collections'
116
-
117
- context "Across mongoid models" do
118
- setup do
119
- class ::Image
120
- include Mongoid::Document
121
- include Elasticsearch::Model
122
- include Elasticsearch::Model::Callbacks
123
-
124
- field :name, type: String
125
- attr_accessible :name if respond_to? :attr_accessible
126
-
127
- settings index: {number_of_shards: 1, number_of_replicas: 0} do
128
- mapping do
129
- indexes :name, type: 'string', analyzer: 'snowball'
130
- indexes :created_at, type: 'date'
131
- end
132
- end
133
-
134
- def as_indexed_json(options={})
135
- as_json(except: [:_id])
136
- end
137
- end
138
-
139
- Image.delete_all
140
- Image.__elasticsearch__.create_index! force: true
141
- Image.create! name: "The Image"
142
- Image.create! name: "A great Image"
143
- Image.create! name: "The greatest Image"
144
- Image.__elasticsearch__.refresh_index!
145
- Image.__elasticsearch__.client.cluster.health wait_for_status: 'yellow'
146
- end
147
-
148
- should "find matching documents across multiple models" do
149
- response = Elasticsearch::Model.search(%q<"greatest Episode" OR "greatest Image"^2>, [Episode, Image])
150
-
151
- assert response.any?, "Response should not be empty: #{response.to_a.inspect}"
152
-
153
- assert_equal 2, response.results.size
154
- assert_equal 2, response.records.size
155
-
156
- assert_instance_of Elasticsearch::Model::Response::Result, response.results.first
157
- assert_instance_of Image, response.records.first
158
- assert_instance_of Episode, response.records.last
159
-
160
- assert_equal 'The greatest Image', response.results[0].name
161
- assert_equal 'The greatest Image', response.records[0].name
162
-
163
- assert_equal 'The greatest Episode', response.results[1].name
164
- assert_equal 'The greatest Episode', response.records[1].name
165
- end
166
- end
167
- end
168
-
169
- end
170
- end
171
- end
172
- end