elastic_searchable 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CONTRIBUTORS.txt +6 -0
- data/LICENSE.txt +19 -17
- data/README.md +51 -0
- data/lib/elastic_searchable.rb +8 -0
- data/lib/elastic_searchable/index.rb +6 -6
- data/lib/elastic_searchable/queries.rb +18 -2
- data/lib/elastic_searchable/version.rb +1 -1
- data/test/test_elastic_searchable.rb +33 -1
- metadata +6 -5
- data/README.rdoc +0 -41
data/CONTRIBUTORS.txt
ADDED
data/LICENSE.txt
CHANGED
@@ -1,20 +1,22 @@
|
|
1
|
-
|
1
|
+
The MIT License
|
2
2
|
|
3
|
-
|
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
|
-
|
12
|
-
|
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
|
+
|
data/lib/elastic_searchable.rb
CHANGED
@@ -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}
|
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
|
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
|
83
|
-
actions << {:index => {'_index' => index_name, '_type' => index_type, '_id' => record.id}}
|
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
|
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}
|
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) }
|
@@ -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' }}}
|
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:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 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-
|
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.
|
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
|
-
|