elastic_searchable 1.1.1 → 1.1.2

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.
data/CONTRIBUTORS.txt ADDED
@@ -0,0 +1,6 @@
1
+ Ryan Sonnek - Original Author
2
+
3
+
4
+ Complete list of contributors:
5
+ https://github.com/socialcast/elastic_searchable/contributors
6
+
data/LICENSE.txt CHANGED
@@ -1,20 +1,22 @@
1
- Copyright (c) 2011 Ryan Sonnek
1
+ The MIT License
2
2
 
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
3
+ Copyright (c) 2011 Socialcast, Inc
10
4
 
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
13
22
 
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # elastic_searchable
2
+
3
+ Integrate the elasticsearch library into Rails.
4
+
5
+ ## Usage
6
+
7
+ ```ruby
8
+ class Blog < ActiveRecord::Base
9
+ elastic_searchable
10
+ end
11
+
12
+ results = Blog.search 'foo'
13
+ ```
14
+
15
+ ## Features
16
+
17
+ * fast. fast! FAST! 30% faster than rubberband on average.
18
+ * active record callbacks automatically keep search index up to date as your data changes
19
+ * out of the box background indexing of data using backgrounded. Don't lock up a foreground process waiting on a background job!
20
+ * integrates with will_paginate library for easy pagination of search results
21
+
22
+ ## Installation
23
+
24
+ ```ruby
25
+ # Bundler Gemfile
26
+ gem 'elastic_searchable'
27
+ ```
28
+
29
+ ## Configuration
30
+
31
+ ```ruby
32
+ # config/initializers/elastic_searchable.rb
33
+ # (optional) customize elasticsearch host
34
+ # default is localhost:9200
35
+ ElasticSearchable.base_uri = 'server:9200'
36
+ ```
37
+
38
+ ## Contributing
39
+
40
+ * Fork the project
41
+ * Fix the issue
42
+ * Add unit tests
43
+ * Submit pull request on github
44
+
45
+ See CONTRIBUTORS.txt for list of project contributors
46
+
47
+ ## Copyright
48
+
49
+ Copyright (c) 2011 Socialcast, Inc.
50
+ See LICENSE.txt for further details.
51
+
@@ -22,11 +22,19 @@ module ElasticSearchable
22
22
  def offline?
23
23
  !!@offline
24
24
  end
25
+ # encapsulate encoding hash into json string
26
+ # support Yajl encoder if installed
27
+ def encode_json(options = {})
28
+ defined?(Yajl) ? Yajl::Encoder.encode(options) : ActiveSupport::JSON.encode(options)
29
+ end
25
30
  # perform a request to the elasticsearch server
26
31
  # configuration:
27
32
  # ElasticSearchable.base_uri 'host:port' controls where to send request to
28
33
  # ElasticSearchable.debug_output outputs all http traffic to console
29
34
  def request(method, url, options = {})
35
+ options.merge! :headers => {'Content-Type' => 'application/json'}
36
+ options.merge! :body => ElasticSearchable.encode_json(options[:body]) if options[:body]
37
+
30
38
  response = self.send(method, url, options)
31
39
  logger.debug "elasticsearch request: #{method} #{url} #{"took #{response['took']}ms" if response['took']}"
32
40
  validate_response response
@@ -13,7 +13,7 @@ module ElasticSearchable
13
13
  # http://www.elasticsearch.com/docs/elasticsearch/rest_api/admin/indices/put_mapping/
14
14
  def update_index_mapping
15
15
  if mapping = self.elastic_options[:mapping]
16
- ElasticSearchable.request :put, index_type_path('_mapping'), :body => {index_type => mapping}.to_json
16
+ ElasticSearchable.request :put, index_type_path('_mapping'), :body => {index_type => mapping}
17
17
  end
18
18
  end
19
19
 
@@ -23,7 +23,7 @@ module ElasticSearchable
23
23
  options = {}
24
24
  options.merge! :settings => self.elastic_options[:index_options] if self.elastic_options[:index_options]
25
25
  options.merge! :mappings => {index_type => self.elastic_options[:mapping]} if self.elastic_options[:mapping]
26
- ElasticSearchable.request :put, index_path, :body => options.to_json
26
+ ElasticSearchable.request :put, index_path, :body => options
27
27
  end
28
28
 
29
29
  # explicitly refresh the index, making all operations performed since the last refresh
@@ -79,8 +79,8 @@ module ElasticSearchable
79
79
  records.each do |record|
80
80
  next unless record.should_index?
81
81
  begin
82
- doc = record.as_json_for_index.to_json
83
- actions << {:index => {'_index' => index_name, '_type' => index_type, '_id' => record.id}}.to_json
82
+ doc = ElasticSearchable.encode_json(record.as_json_for_index)
83
+ actions << ElasticSearchable.encode_json({:index => {'_index' => index_name, '_type' => index_type, '_id' => record.id}})
84
84
  actions << doc
85
85
  rescue => e
86
86
  ElasticSearchable.logger.warn "Unable to bulk index record: #{record.inspect} [#{e.message}]"
@@ -114,7 +114,7 @@ module ElasticSearchable
114
114
  def reindex(lifecycle = nil)
115
115
  query = {}
116
116
  query.merge! :percolate => "*" if _percolate_callbacks.any?
117
- response = ElasticSearchable.request :put, self.class.index_type_path(self.id), :query => query, :body => self.as_json_for_index.to_json
117
+ response = ElasticSearchable.request :put, self.class.index_type_path(self.id), :query => query, :body => self.as_json_for_index
118
118
 
119
119
  self.index_lifecycle = lifecycle ? lifecycle.to_sym : nil
120
120
  _run_index_callbacks
@@ -139,7 +139,7 @@ module ElasticSearchable
139
139
  # can be done automatically when indexing using :percolate => true config option
140
140
  # http://www.elasticsearch.org/blog/2011/02/08/percolator.html
141
141
  def percolate
142
- response = ElasticSearchable.request :get, self.class.index_type_path('_percolate'), :body => {:doc => self.as_json_for_index}.to_json
142
+ response = ElasticSearchable.request :get, self.class.index_type_path('_percolate'), :body => {:doc => self.as_json_for_index}
143
143
  self.percolations = response['matches'] || []
144
144
  self.percolations
145
145
  end
@@ -13,11 +13,27 @@ module ElasticSearchable
13
13
  def search(query, options = {})
14
14
  page = (options.delete(:page) || 1).to_i
15
15
  options[:fields] ||= '_id'
16
- options[:q] ||= query
17
16
  options[:size] ||= per_page_for_search(options)
18
17
  options[:from] ||= options[:size] * (page - 1)
18
+ if query.is_a?(Hash)
19
+ options[:query] = query
20
+ else
21
+ options[:query] = {
22
+ :query_string => {
23
+ :query => query,
24
+ :default_operator => options.delete(:default_operator)
25
+ }
26
+ }
27
+ end
28
+ query = {}
29
+ case sort = options.delete(:sort)
30
+ when Array,Hash
31
+ options[:sort] = sort
32
+ when String
33
+ query[:sort] = sort
34
+ end
19
35
 
20
- response = ElasticSearchable.request :get, index_type_path('_search'), :query => options
36
+ response = ElasticSearchable.request :get, index_type_path('_search'), :query => query, :body => options
21
37
  hits = response['hits']
22
38
  ids = hits['hits'].collect {|h| h['_id'].to_i }
23
39
  results = self.find(ids).sort_by {|result| ids.index(result.id) }
@@ -1,4 +1,4 @@
1
1
  module ElasticSearchable
2
- VERSION = '1.1.1'
2
+ VERSION = '1.1.2'
3
3
  end
4
4
 
@@ -195,6 +195,28 @@ class TestElasticSearchable < Test::Unit::TestCase
195
195
  assert_nil @results.next_page
196
196
  end
197
197
  end
198
+
199
+ context 'searching for results using a query Hash' do
200
+ setup do
201
+ @results = Post.search({
202
+ :filtered => {
203
+ :query => {
204
+ :term => {:title => 'foo'},
205
+ },
206
+ :filter => {
207
+ :or => [
208
+ {:term => {:body => 'second'}},
209
+ {:term => {:body => 'third'}}
210
+ ]
211
+ }
212
+ }
213
+ })
214
+ end
215
+ should 'find only the object which ' do
216
+ assert_does_not_contain @results, @first_post
217
+ assert_contains @results, @second_post
218
+ end
219
+ end
198
220
 
199
221
  context 'searching for second page using will_paginate params' do
200
222
  setup do
@@ -223,6 +245,16 @@ class TestElasticSearchable < Test::Unit::TestCase
223
245
  assert_equal @first_post, @results.last
224
246
  end
225
247
  end
248
+
249
+ context 'advanced sort options' do
250
+ setup do
251
+ @results = Post.search 'foo', :sort => [{:id => 'desc'}]
252
+ end
253
+ should 'sort results correctly' do
254
+ assert_equal @second_post, @results.first
255
+ assert_equal @first_post, @results.last
256
+ end
257
+ end
226
258
 
227
259
  context 'destroying one object' do
228
260
  setup do
@@ -353,7 +385,7 @@ class TestElasticSearchable < Test::Unit::TestCase
353
385
  end
354
386
  context "when index has configured percolation" do
355
387
  setup do
356
- ElasticSearchable.request :put, '/_percolator/elastic_searchable/myfilter', :body => {:query => {:query_string => {:query => 'foo' }}}.to_json
388
+ ElasticSearchable.request :put, '/_percolator/elastic_searchable/myfilter', :body => {:query => {:query_string => {:query => 'foo' }}}
357
389
  ElasticSearchable.request :post, '/_percolator/_refresh'
358
390
  end
359
391
  context 'creating an object that does not match the percolation' do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastic_searchable
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 1
10
- version: 1.1.1
9
+ - 2
10
+ version: 1.1.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Sonnek
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-15 00:00:00 Z
18
+ date: 2011-04-28 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activerecord
@@ -181,9 +181,10 @@ files:
181
181
  - .document
182
182
  - .gitignore
183
183
  - .rvmrc
184
+ - CONTRIBUTORS.txt
184
185
  - Gemfile
185
186
  - LICENSE.txt
186
- - README.rdoc
187
+ - README.md
187
188
  - Rakefile
188
189
  - elastic_searchable.gemspec
189
190
  - lib/elastic_searchable.rb
data/README.rdoc DELETED
@@ -1,41 +0,0 @@
1
- = elastic_searchable
2
-
3
- Integrate the elasticsearch library into Rails.
4
-
5
- == Usage
6
- class Blog < ActiveRecord::Base
7
- elastic_searchable
8
- end
9
-
10
- results = Blog.search 'foo'
11
-
12
- == Features
13
-
14
- * fast. fast! FAST! 30% faster than rubberband on average.
15
- * active record callbacks automatically keep search index up to date as your data changes
16
- * out of the box background indexing of data using backgrounded. Don't lock up a foreground process waiting on a background job!
17
- * integrates with will_paginate library for easy pagination of search results
18
-
19
- == Installation
20
- #Gemfile
21
- gem 'elastic_searchable'
22
-
23
- == Configuration
24
-
25
- #config/initializers/elastic_searchable.rb
26
- #customize elasticsearch host
27
- #defaults to localhost:9200
28
- ElasticSearchable.base_uri = 'server:9200'
29
-
30
- == Contributing
31
-
32
- * Fork the project
33
- * Fix the issue
34
- * Add unit tests
35
- * Submit pull request on github
36
-
37
- == Copyright
38
-
39
- Copyright (c) 2011 Ryan Sonnek. See LICENSE.txt for
40
- further details.
41
-