wj-mongoid-elasticsearch 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e3d100f567a331d026d6f11af5855250a175d000
4
+ data.tar.gz: 19941f55187e0dfae9fe24939174b2d321d8ace4
5
+ SHA512:
6
+ metadata.gz: aa17df21a93b08424b850ff8acc18be1242d0d3b8c34f646d1cce05d3521ff30708b815d4f21dacde93505c6155647aacdf849141e4cedc26af0193c9968200f
7
+ data.tar.gz: 9e2de6a5c3c73e9a17594c4134e04b23d999424240e81c7fc413d42d92a665bc39a741110326b8972ee954c5ea4eb6330e4bbeb34d37a3b5098ce6e3f0781eba
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ doc/
10
+ lib/bundler/man
11
+ pkg
12
+ rdoc
13
+ spec/reports
14
+ test/tmp
15
+ test/version_tmp
16
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ mongoid-elasticsearch
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2.3
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ services:
2
+ - mongodb
3
+ - elasticsearch
4
+
5
+ notifications:
6
+ email: false
7
+
8
+ language: ruby
9
+ rvm:
10
+ - 2.2.3
11
+
12
+ gemfile:
13
+ - Gemfile
14
+
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ ## 0.8.1 (March 4, 2014) ##
2
+
3
+ * New method "Model.without_es_update!" to temporally disable callbacks (ie, for testing) (by [@xronos-i-am](https://github.com/xronos-i-am))
4
+
5
+ ## 0.8.0 (March 4, 2014) ##
6
+
7
+ * fix results with :load wrapper #6 (by [@xronos-i-am](https://github.com/xronos-i-am))
8
+ * Added option to prevent automatic creating of index. #7 (thx [@intrica](https://github.com/intrica))
9
+ * use after_initalize to create indexes later in the app boot process
10
+
11
+ Set Mongoid::Elasticsearch.autocreate_indexes to false in an initalizer to prevent automatic creation for all indexes.
12
+
13
+ You can always use ```rake es:create``` to create all indexes or call Mongoid::Elasticsearch.create_all_indexes!.
14
+
15
+ Indexes defined with skip_create: true are not created with all other indexes and must be created manually with Model.es.index.create
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongoid-elasticsearch.gemspec
4
+ gem 'database_cleaner', github: 'DatabaseCleaner/database_cleaner'
5
+ gemspec
6
+
data/Gemfile.lock ADDED
@@ -0,0 +1,149 @@
1
+ GIT
2
+ remote: git://github.com/DatabaseCleaner/database_cleaner.git
3
+ revision: 49ca0f3e8ac4c096129442d0f942d39f2c0d7dde
4
+ specs:
5
+ database_cleaner (1.5.2)
6
+
7
+ PATH
8
+ remote: .
9
+ specs:
10
+ mongoid-elasticsearch (0.9.1)
11
+ elasticsearch (~> 1.0.13)
12
+ mongoid (>= 3.0, < 6.0)
13
+ ruby-progressbar
14
+
15
+ GEM
16
+ remote: https://rubygems.org/
17
+ specs:
18
+ actionpack (4.2.6)
19
+ actionview (= 4.2.6)
20
+ activesupport (= 4.2.6)
21
+ rack (~> 1.6)
22
+ rack-test (~> 0.6.2)
23
+ rails-dom-testing (~> 1.0, >= 1.0.5)
24
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
25
+ actionview (4.2.6)
26
+ activesupport (= 4.2.6)
27
+ builder (~> 3.1)
28
+ erubis (~> 2.7.0)
29
+ rails-dom-testing (~> 1.0, >= 1.0.5)
30
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
31
+ activemodel (4.2.6)
32
+ activesupport (= 4.2.6)
33
+ builder (~> 3.1)
34
+ activesupport (4.2.6)
35
+ i18n (~> 0.7)
36
+ json (~> 1.7, >= 1.7.7)
37
+ minitest (~> 5.1)
38
+ thread_safe (~> 0.3, >= 0.3.4)
39
+ tzinfo (~> 1.1)
40
+ bson (4.1.0)
41
+ builder (3.2.2)
42
+ coveralls (0.8.13)
43
+ json (~> 1.8)
44
+ simplecov (~> 0.11.0)
45
+ term-ansicolor (~> 1.3)
46
+ thor (~> 0.19.1)
47
+ tins (~> 1.6.0)
48
+ diff-lcs (1.2.5)
49
+ docile (1.1.5)
50
+ elasticsearch (1.0.17)
51
+ elasticsearch-api (= 1.0.17)
52
+ elasticsearch-transport (= 1.0.17)
53
+ elasticsearch-api (1.0.17)
54
+ multi_json
55
+ elasticsearch-transport (1.0.17)
56
+ faraday
57
+ multi_json
58
+ erubis (2.7.0)
59
+ faraday (0.9.2)
60
+ multipart-post (>= 1.2, < 3)
61
+ glebtv-httpclient (3.2.8)
62
+ lru_redux
63
+ hashie (3.4.3)
64
+ i18n (0.7.0)
65
+ json (1.8.3)
66
+ kaminari (0.16.3)
67
+ actionpack (>= 3.0.0)
68
+ activesupport (>= 3.0.0)
69
+ loofah (2.0.3)
70
+ nokogiri (>= 1.5.9)
71
+ lru_redux (1.1.0)
72
+ mini_portile2 (2.0.0)
73
+ minitest (5.8.4)
74
+ mongo (2.2.4)
75
+ bson (~> 4.0)
76
+ mongoid (5.1.2)
77
+ activemodel (~> 4.0)
78
+ mongo (~> 2.1)
79
+ origin (~> 2.2)
80
+ tzinfo (>= 0.3.37)
81
+ mongoid-compatibility (0.3.1)
82
+ activesupport
83
+ mongoid (>= 2.0)
84
+ mongoid-slug (5.0.0)
85
+ mongoid (>= 3.0)
86
+ mongoid-compatibility
87
+ stringex (~> 2.0)
88
+ multi_json (1.11.2)
89
+ multipart-post (2.0.0)
90
+ nokogiri (1.6.7.2)
91
+ mini_portile2 (~> 2.0.0.rc2)
92
+ origin (2.2.0)
93
+ rack (1.6.4)
94
+ rack-test (0.6.3)
95
+ rack (>= 1.0)
96
+ rails-deprecated_sanitizer (1.0.3)
97
+ activesupport (>= 4.2.0.alpha)
98
+ rails-dom-testing (1.0.7)
99
+ activesupport (>= 4.2.0.beta, < 5.0)
100
+ nokogiri (~> 1.6.0)
101
+ rails-deprecated_sanitizer (>= 1.0.1)
102
+ rails-html-sanitizer (1.0.3)
103
+ loofah (~> 2.0)
104
+ rake (11.1.2)
105
+ rspec (3.4.0)
106
+ rspec-core (~> 3.4.0)
107
+ rspec-expectations (~> 3.4.0)
108
+ rspec-mocks (~> 3.4.0)
109
+ rspec-core (3.4.4)
110
+ rspec-support (~> 3.4.0)
111
+ rspec-expectations (3.4.0)
112
+ diff-lcs (>= 1.2.0, < 2.0)
113
+ rspec-support (~> 3.4.0)
114
+ rspec-mocks (3.4.1)
115
+ diff-lcs (>= 1.2.0, < 2.0)
116
+ rspec-support (~> 3.4.0)
117
+ rspec-support (3.4.1)
118
+ ruby-progressbar (1.7.5)
119
+ simplecov (0.11.2)
120
+ docile (~> 1.1.0)
121
+ json (~> 1.8)
122
+ simplecov-html (~> 0.10.0)
123
+ simplecov-html (0.10.0)
124
+ stringex (2.6.0)
125
+ term-ansicolor (1.3.2)
126
+ tins (~> 1.0)
127
+ thor (0.19.1)
128
+ thread_safe (0.3.5)
129
+ tins (1.6.0)
130
+ tzinfo (1.2.2)
131
+ thread_safe (~> 0.1)
132
+
133
+ PLATFORMS
134
+ ruby
135
+
136
+ DEPENDENCIES
137
+ bundler
138
+ coveralls
139
+ database_cleaner!
140
+ glebtv-httpclient
141
+ hashie
142
+ kaminari
143
+ mongoid-elasticsearch!
144
+ mongoid-slug (~> 5.0.0)
145
+ rake
146
+ rspec
147
+
148
+ BUNDLED WITH
149
+ 1.11.2
data/MIT-LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 glebtv
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,258 @@
1
+ # Mongoid::Elasticsearch
2
+
3
+ [![Build Status](https://travis-ci.org/rs-pro/mongoid-elasticsearch.png?branch=master)](https://travis-ci.org/rs-pro/mongoid-elasticsearch)
4
+ [![Coverage Status](https://coveralls.io/repos/rs-pro/mongoid-elasticsearch/badge.png?branch=master)](https://coveralls.io/r/rs-pro/mongoid-elasticsearch?branch=master)
5
+ [![Gem Version](https://badge.fury.io/rb/mongoid-elasticsearch.png)](http://badge.fury.io/rb/mongoid-elasticsearch)
6
+ [![Dependency Status](https://www.versioneye.com/user/projects/53e73fe735080d1e4d00009c/badge.svg)](https://www.versioneye.com/user/projects/53e73fe735080d1e4d00009c)
7
+ [![Issues](http://img.shields.io/github/issues/rs-pro/mongoid-elasticsearch.svg)](https://github.com/rs-pro/mongoid-elasticsearch/issues)
8
+ [![License](http://img.shields.io/:license-mit-blue.svg)](https://github.com/rs-pro/mongoid-elasticsearch/blob/master/MIT-LICENSE.txt)
9
+
10
+
11
+ Use [Elasticsearch](http://www.elasticsearch.org/) with mongoid with just a few
12
+ lines of code
13
+
14
+ Allows easy usage of [the new Elasticsearch gem](https://github.com/elasticsearch/elasticsearch-ruby)
15
+ with [Mongoid 4](https://github.com/mongoid/mongoid)
16
+
17
+ ## Features
18
+
19
+ - Uses new elasticsearch gem
20
+ - Has a simple high-level API
21
+ - No weird undocumented DSL, just raw JSON for queries and index definitions
22
+ - Allows for full power of elasticsearch when it's necessary
23
+ - Indexes are automatically created if they don't exist on app boot
24
+ - Works out of the box with zero configuration
25
+ - Multi-model search with real model instances and pagination
26
+ - Whole test suite is run against a real ES instance, no mocks
27
+
28
+ This gem is very simple and does not try hide any part of the ES REST api, it
29
+ just adds some shortcuts for prefixing index names, automatic updating of the index
30
+ when models are added\changed, search with pagination, wrapping results in
31
+ a model instance, ES 0.90.3 new completion suggester, etc (new features coming
32
+ soon)
33
+
34
+ ## Alternatives list:
35
+
36
+ - [Elasticsearch gem](https://github.com/elasticsearch/elasticsearch-ruby) - low-level and hard for simple use-cases
37
+ - [(re)Tire](https://github.com/karmi/retire)
38
+ - [RubberBand](https://github.com/grantr/rubberband) - EOL, no Mongoid
39
+ - [Mebla](https://github.com/cousine/mebla) - long dead
40
+
41
+ ## Installation
42
+
43
+ Add this line to your application's Gemfile:
44
+
45
+ gem 'mongoid-elasticsearch'
46
+
47
+ And then execute:
48
+
49
+ $ bundle
50
+
51
+ Or install it yourself as:
52
+
53
+ $ gem install mongoid-elasticsearch
54
+
55
+ ## Usage
56
+
57
+ ### Basic:
58
+
59
+ class Post
60
+ include Mongoid::Document
61
+ include Mongoid::Elasticsearch
62
+ elasticsearch!
63
+ end
64
+
65
+ Post.es.search 'test text' # shortcut for Post.es.search({q: 'test text'})
66
+ result = Post.es.search body: {query: {...}, facets: {...}} etc
67
+ result.raw_response
68
+ result.results # by default returns an Enumerable with Post instances exactly
69
+ # like they were loaded from MongoDB
70
+ Post.es.index.create # create index (done automatically on app boot)
71
+ Post.es.index.delete # drop index
72
+ Post.es.index.reset # recreate index
73
+ Post.es.index.refresh # force index update (useful for specs)
74
+ Post.es.client # Elasticsearch::Client instance
75
+
76
+ ### Completion:
77
+
78
+ include Mongoid::Elasticsearch
79
+ elasticsearch! index_mappings: {
80
+ name: {
81
+ type: 'multi_field',
82
+ fields: {
83
+ name: {type: 'string', boost: 10},
84
+ suggest: {type: 'completion'}
85
+ }
86
+ },
87
+ desc: {type: 'string'},
88
+ }
89
+
90
+ Post.es.completion('te', 'name.suggest') # requires ES 0.90.3
91
+
92
+ ### Search multiple models:
93
+
94
+ # By default only searches in indexes managed by Mongoid::Elasticsearch
95
+ # to ignore other apps indexes in same ES instance
96
+ response = Mongoid::Elasticsearch.search 'test'
97
+
98
+
99
+ search syntax docs: http://rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions#search-instance_method
100
+
101
+ ES Actions docs: http://rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Actions
102
+
103
+ ES Indices docs: http://rubydoc.info/gems/elasticsearch-api/Elasticsearch/API/Indices/Actions
104
+
105
+ ES docs: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/index.html
106
+
107
+ ### Advanced:
108
+
109
+ prefix all app's index names:
110
+
111
+ Mongoid::Elasticsearch.prefix = 'my_app'
112
+
113
+ default options for Elasticsearch::Client.new (url etc)
114
+
115
+ Mongoid::Elasticsearch.client_options = {hosts: ['localhost']}
116
+
117
+ index definition options and custom model serialization:
118
+
119
+ include Mongoid::Elasticsearch
120
+ elasticsearch!({
121
+ # index name (prefix is added)
122
+ index_name: 'mongoid_es_news',
123
+
124
+ # don't use global name prefix
125
+ prefix_name: false,
126
+
127
+ # elasticsearch index definition
128
+ index_options: {},
129
+
130
+ # or only mappings with empty options
131
+ index_mappings: {
132
+ name: {
133
+ type: 'multi_field',
134
+ fields: {
135
+ name: {type: 'string', analyzer: 'snowball'},
136
+ raw: {type: 'string', index: :not_analyzed},
137
+ suggest: {type: 'completion'}
138
+ }
139
+ },
140
+ tags: {type: 'string', include_in_all: false}
141
+ },
142
+ wrapper: :load
143
+ })
144
+
145
+ # customize what gets sent to elasticsearch:
146
+ def as_indexed_json
147
+ # id field is properly added automatically
148
+ {
149
+ name: name,
150
+ excerpt: excerpt
151
+ }
152
+ # mongoid_slug note: add _slugs to as_indexed_json, NOT slug
153
+ end
154
+
155
+ Example mapping with boost field:
156
+
157
+ elasticsearch!({
158
+ index_name: Rails.env.test? ? 'vv_test_articles' : 'vv_articles',
159
+ index_options: {
160
+ settings: {
161
+ index: {
162
+ analysis: {
163
+ analyzer: {
164
+ my_analyzer: {
165
+ type: "snowball",
166
+ language: "Russian"
167
+ }
168
+ }
169
+ }
170
+ }
171
+ },
172
+ mappings: {
173
+ "articles/article" => {
174
+ _boost: {name: '_boost', null_value: 1},
175
+ properties: {
176
+ name: {type: 'string', boost: 10, analyzer: 'my_analyzer'},
177
+ tags: {type: 'string', analyzer: 'my_analyzer'}
178
+ }
179
+ }
180
+ }
181
+ },
182
+ wrapper: :load
183
+ })
184
+
185
+
186
+ [Mapping definition docs](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-core-types.html)
187
+
188
+ ### Pagination
189
+
190
+ ```= paginate @posts``` should work as normal with Kaminari after you do:
191
+
192
+ @posts = Post.es.search(params[:search], page: params[:page])
193
+ # or
194
+ @posts = Post.es.search({
195
+ body: {
196
+ query: {
197
+ query_string: {
198
+ query: params[:search]
199
+ }
200
+ },
201
+ filter: {
202
+ term: {community_id: @community.id.to_s}
203
+ }
204
+ }},
205
+ page: params[:page], wrapper: :load
206
+ )
207
+
208
+ ### Reindexing
209
+
210
+ #### All models
211
+
212
+ ```rake es:reindex``` will reindex all indices managed by Mongoid::Elasticsearch
213
+
214
+ #### One model - Simple bulk
215
+
216
+ This is the preferred (fastest) method to reindex everything
217
+
218
+ Music::Video.es.index_all
219
+
220
+ #### One model - Simple
221
+
222
+ Communities::Thread.es.index.reset
223
+ Communities::Thread.enabled.each do |ingr|
224
+ ingr.es_update
225
+ end
226
+
227
+ ### Possible wrappers for results:
228
+
229
+ - :hash - raw hash from ES
230
+ - :mash - [Hashie::Mash](https://github.com/intridea/hashie#mash) (gem '[hashie](https://github.com/intridea/hashie)' must be added to gemfile)
231
+ - :load - load each found model by ID from database
232
+ - :model - create a model instance from data stored in elasticsearch
233
+
234
+ See more examples in specs.
235
+
236
+ ### Index creation
237
+
238
+ This gem by default automatically creates indexes for all configured models on application startup.
239
+
240
+ Set ```Mongoid::Elasticsearch.autocreate_indexes = false``` in an initalizer to prevent automatic creation for all indexes.
241
+
242
+ You can always use ```rake es:create``` to create all indexes or call ```Mongoid::Elasticsearch.create_all_indexes!```.
243
+
244
+ Indexes defined with option ```skip_create: true``` are not created with all other indexes and must be created manually with ```Model.es.index.create```
245
+
246
+
247
+ #### Util
248
+
249
+ # Escape string so it can be safely passed to ES (removes all special characters)
250
+ Mongoid::Elasticsearch::Utils.clean(s)
251
+
252
+ ## Contributing
253
+
254
+ 1. Fork it
255
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
256
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
257
+ 4. Push to the branch (`git push origin my-new-feature`)
258
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ desc 'Default: run specs.'
6
+ task :default => :spec
7
+
8
+ desc "Run specs"
9
+ RSpec::Core::RakeTask.new
@@ -0,0 +1,40 @@
1
+ module Mongoid
2
+ module Elasticsearch
3
+ module Callbacks
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ after_save :update_es_index
8
+ after_destroy :update_es_index
9
+
10
+ ## THIS FUNCTION HAS BEEN UPDATED TO DO THE UPDATE ONLY IF THE OP_SUCCESS IS TRUE OR NIL, IN CASE THE RECORD RESPONDS TO OP_SUCCESS.
11
+ def update_es_index
12
+ if self.respond_to? :op_success
13
+ if self.op_success.nil?
14
+ es_update
15
+ else
16
+ es_update if self.op_success == true
17
+ end
18
+ else
19
+ es_update
20
+ end
21
+ end
22
+ end
23
+
24
+ module ClassMethods
25
+ def without_es_update!( &block )
26
+ skip_callback( :save, :after, :update_es_index )
27
+ skip_callback( :destroy, :after, :update_es_index )
28
+
29
+ result = yield
30
+
31
+ set_callback( :save, :after, :update_es_index )
32
+ set_callback( :destroy, :after, :update_es_index )
33
+
34
+ result
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,111 @@
1
+ module Mongoid
2
+ module Elasticsearch
3
+ class Es
4
+ INDEX_STEP = 100
5
+ attr_reader :klass, :version
6
+
7
+ def initialize(klass)
8
+ @klass = klass
9
+ @version = Gem::Version.new(client.info['version']['number'])
10
+ end
11
+
12
+ def client
13
+ # dup is needed because Elasticsearch::Client.new changes options hash inplace
14
+ @client ||= ::Elasticsearch::Client.new klass.es_client_options.dup
15
+ end
16
+
17
+ def index
18
+ @index ||= Index.new(self)
19
+ end
20
+
21
+ def index_all(step_size = INDEX_STEP)
22
+ index.reset
23
+ q = klass.asc(:id)
24
+ steps = (q.count / step_size) + 1
25
+ last_id = nil
26
+ steps.times do |step|
27
+ if last_id
28
+ docs = q.gt(id: last_id).limit(step_size).to_a
29
+ else
30
+ docs = q.limit(step_size).to_a
31
+ end
32
+ last_id = docs.last.try(:id)
33
+ docs = docs.map do |obj|
34
+ if obj.es_index?
35
+ { index: {data: obj.as_indexed_json}.merge(_id: obj.id.to_s) }
36
+ else
37
+ nil
38
+ end
39
+ end.reject { |obj| obj.nil? }
40
+ next if docs.empty?
41
+ client.bulk({body: docs}.merge(type_options))
42
+ if block_given?
43
+ yield steps, step
44
+ end
45
+ end
46
+ end
47
+
48
+ def search(query, options = {})
49
+ if query.is_a?(String)
50
+ query = {q: Utils.clean(query)}
51
+ end
52
+
53
+ page = options[:page]
54
+ per_page = options[:per_page].nil? ? options[:per] : options[:per_page]
55
+
56
+ query[:size] = ( per_page.to_i ) if per_page
57
+ query[:from] = ( page.to_i <= 1 ? 0 : (per_page.to_i * (page.to_i-1)) ) if page && per_page
58
+
59
+ options[:wrapper] ||= klass.es_wrapper
60
+
61
+ Response.new(client, query.merge(custom_type_options(options)), false, klass, options)
62
+ end
63
+
64
+ def all(options = {})
65
+ search({body: {query: {match_all: {}}}}, options)
66
+ end
67
+
68
+ def options_for(obj)
69
+ {id: obj.id.to_s}.merge type_options
70
+ end
71
+
72
+ def custom_type_options(options)
73
+ if !options[:include_type].nil? && options[:include_type] == false
74
+ {index: index.name}
75
+ else
76
+ type_options
77
+ end
78
+ end
79
+
80
+ def type_options
81
+ {index: index.name, type: index.type}
82
+ end
83
+
84
+ def index_item(obj)
85
+ client.index({body: obj.as_indexed_json}.merge(options_for(obj)))
86
+ end
87
+
88
+ def remove_item(obj)
89
+ client.delete(options_for(obj).merge(ignore: 404))
90
+ end
91
+
92
+ def completion_supported?
93
+ @version > Gem::Version.new('0.90.2')
94
+ end
95
+
96
+ def completion(text, field = "suggest")
97
+ raise "Completion not supported in ES #{@version}" unless completion_supported?
98
+ body = {
99
+ q: {
100
+ text: Utils.clean(text),
101
+ completion: {
102
+ field: field
103
+ }
104
+ }
105
+ }
106
+ results = client.suggest(index: index.name, body: body)
107
+ results['q'][0]['options']
108
+ end
109
+ end
110
+ end
111
+ end