slingshot-rb 0.0.2 → 0.0.3
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/README.markdown +17 -2
- data/lib/slingshot/configuration.rb +9 -0
- data/lib/slingshot/dsl.rb +2 -2
- data/lib/slingshot/results/collection.rb +7 -3
- data/lib/slingshot/results/item.rb +2 -2
- data/lib/slingshot/search.rb +5 -1
- data/lib/slingshot/version.rb +1 -1
- data/test/unit/configuration_test.rb +19 -0
- data/test/unit/results_collection_test.rb +38 -6
- data/test/unit/results_item_test.rb +15 -0
- metadata +4 -4
data/README.markdown
CHANGED
@@ -13,7 +13,7 @@ You should seriously consider it to power search in your Ruby applications:
|
|
13
13
|
it will deliver all the features you want — and many more you may have not
|
14
14
|
imagined yet (native geo search? histogram facets?)
|
15
15
|
|
16
|
-
_Slingshot_ currently
|
16
|
+
_Slingshot_ currently allows basic operation with the index and searching. More is planned.
|
17
17
|
|
18
18
|
|
19
19
|
Installation
|
@@ -32,6 +32,7 @@ OK, easy. Now, install the gem via Rubygems:
|
|
32
32
|
or from source:
|
33
33
|
|
34
34
|
$ git clone git://github.com/karmi/slingshot.git
|
35
|
+
$ cd slingshot
|
35
36
|
$ rake install
|
36
37
|
|
37
38
|
|
@@ -132,6 +133,13 @@ Currently, _Slingshot_ supports only a limited subset of vast _ElasticSearch_ [S
|
|
132
133
|
|
133
134
|
See the [`examples/dsl.rb`](blob/master/examples/dsl.rb).
|
134
135
|
|
136
|
+
_Slingshot_ wraps the results in a enumerable `Results::Collection` class, and every result in a `Results::Item` class,
|
137
|
+
which looks like a child of `Hash` and `Openstruct`.
|
138
|
+
|
139
|
+
You may wrap the result items in your own class by setting the `Configuration.wrapper` property.
|
140
|
+
Check out file `test/unit/results_collection_test.rb` to see how to do that.
|
141
|
+
|
142
|
+
|
135
143
|
Todo & Plans
|
136
144
|
------------
|
137
145
|
|
@@ -139,11 +147,11 @@ In order of importance:
|
|
139
147
|
|
140
148
|
* Getting document [by ID](http://www.elasticsearch.org/guide/reference/api/get.html)
|
141
149
|
* Seamless _ActiveModel_ compatibility for easy usage in _Rails_ applications (this also means nearly full _ActiveRecord_ compatibility)
|
142
|
-
* Allowing to set custom non-ActiveModel wrapper class (your own)
|
143
150
|
* Seamless [will_paginate](https://github.com/mislav/will_paginate) compatibility for easy pagination
|
144
151
|
* [Histogram](http://www.elasticsearch.org/guide/reference/api/search/facets/histogram-facet.html) facets
|
145
152
|
* Seamless support for [auto-updating _river_ index](http://www.elasticsearch.org/guide/reference/river/couchdb.html) for _CouchDB_ `_changes` feed
|
146
153
|
* [Mapping](http://www.elasticsearch.org/guide/reference/mapping/) management
|
154
|
+
* Proper RDoc annotations for the source code
|
147
155
|
* Infrastructure for query filters
|
148
156
|
* [Range](http://www.elasticsearch.org/guide/reference/query-dsl/range-filter.html) filters and queries
|
149
157
|
* [Geo Filters](http://www.elasticsearch.org/blog/2010/08/16/geo_location_and_search.html) for queries
|
@@ -155,6 +163,13 @@ In order of importance:
|
|
155
163
|
* [Bulk](http://www.elasticsearch.org/guide/reference/api/bulk.html) API
|
156
164
|
* Embedded webserver to display cluster statistics and allow easy searches
|
157
165
|
|
166
|
+
|
167
|
+
Other Clients
|
168
|
+
-------------
|
169
|
+
|
170
|
+
Check out [other _ElasticSearch_ clients](http://www.elasticsearch.org/guide/appendix/clients.html).
|
171
|
+
|
172
|
+
|
158
173
|
Feedback
|
159
174
|
--------
|
160
175
|
|
@@ -10,6 +10,15 @@ module Slingshot
|
|
10
10
|
@client = klass || @client || Client::RestClient
|
11
11
|
end
|
12
12
|
|
13
|
+
def self.wrapper(klass=nil)
|
14
|
+
@wrapper = klass || @wrapper || Results::Item
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.reset(*properties)
|
18
|
+
reset_variables = properties.empty? ? instance_variables : instance_variables & properties.map { |p| "@#{p}" }
|
19
|
+
reset_variables.each { |v| instance_variable_set(v, nil) }
|
20
|
+
end
|
21
|
+
|
13
22
|
end
|
14
23
|
|
15
24
|
end
|
data/lib/slingshot/dsl.rb
CHANGED
@@ -5,8 +5,8 @@ module Slingshot
|
|
5
5
|
Configuration.class_eval(&block)
|
6
6
|
end
|
7
7
|
|
8
|
-
def search(indices, &block)
|
9
|
-
Search::Search.new(indices, &block).perform
|
8
|
+
def search(indices, options={}, &block)
|
9
|
+
Search::Search.new(indices, options, &block).perform
|
10
10
|
end
|
11
11
|
|
12
12
|
def index(name, &block)
|
@@ -9,9 +9,13 @@ module Slingshot
|
|
9
9
|
@time = response['took']
|
10
10
|
@total = response['hits']['total']
|
11
11
|
@results = response['hits']['hits'].map do |h|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
if Configuration.wrapper == Hash
|
13
|
+
h
|
14
|
+
else
|
15
|
+
document = h['_source'] ? h['_source'] : h['fields']
|
16
|
+
h.update document if document
|
17
|
+
Configuration.wrapper.new(h)
|
18
|
+
end
|
15
19
|
end
|
16
20
|
@facets = response['facets']
|
17
21
|
end
|
@@ -13,7 +13,7 @@ module Slingshot
|
|
13
13
|
end
|
14
14
|
super.replace self
|
15
15
|
else
|
16
|
-
super
|
16
|
+
super
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -25,7 +25,7 @@ module Slingshot
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def inspect
|
28
|
-
s = []; self.each { |k,v| s << "
|
28
|
+
s = []; self.each { |k,v| s << "#{k}: #{v.inspect}" }
|
29
29
|
%Q|<Item #{s.join(', ')}>|
|
30
30
|
end
|
31
31
|
|
data/lib/slingshot/search.rb
CHANGED
@@ -6,8 +6,12 @@ module Slingshot
|
|
6
6
|
attr_reader :indices, :url, :results, :response, :query, :facets
|
7
7
|
|
8
8
|
def initialize(*indices, &block)
|
9
|
-
|
9
|
+
@options = indices.pop if indices.last.is_a?(Hash)
|
10
10
|
@indices = indices
|
11
|
+
raise ArgumentError, 'Please pass index or indices to search' if @indices.empty?
|
12
|
+
if @options
|
13
|
+
Configuration.wrapper @options[:wrapper] if @options[:wrapper]
|
14
|
+
end
|
11
15
|
instance_eval(&block) if block_given?
|
12
16
|
end
|
13
17
|
|
data/lib/slingshot/version.rb
CHANGED
@@ -27,6 +27,25 @@ module Slingshot
|
|
27
27
|
assert_nothing_raised { Configuration.client Client::Base }
|
28
28
|
assert_equal Client::Base, Configuration.client
|
29
29
|
end
|
30
|
+
|
31
|
+
should "allow to reset the configuration for specific property" do
|
32
|
+
Configuration.url 'http://example.com'
|
33
|
+
Configuration.client Client::Base
|
34
|
+
assert_equal 'http://example.com', Configuration.url
|
35
|
+
Configuration.reset :url
|
36
|
+
assert_equal 'http://localhost:9200', Configuration.url
|
37
|
+
assert_equal Client::Base, Configuration.client
|
38
|
+
end
|
39
|
+
|
40
|
+
should "allow to reset the configuration for all properties" do
|
41
|
+
Configuration.url 'http://example.com'
|
42
|
+
Configuration.client Client::Base
|
43
|
+
assert_equal 'http://example.com', Configuration.url
|
44
|
+
assert_equal Client::Base, Configuration.client
|
45
|
+
Configuration.reset
|
46
|
+
assert_equal 'http://localhost:9200', Configuration.url
|
47
|
+
assert_equal Client::RestClient, Configuration.client
|
48
|
+
end
|
30
49
|
end
|
31
50
|
|
32
51
|
end
|
@@ -1,11 +1,24 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
+
class Article
|
4
|
+
attr_reader :title, :body
|
5
|
+
def initialize(attributes={})
|
6
|
+
@title = attributes[:title]
|
7
|
+
@body = attributes[:body]
|
8
|
+
end
|
9
|
+
def to_json
|
10
|
+
{ :title => @title, :body => @body }.to_json
|
11
|
+
end
|
12
|
+
alias :to_indexed_json :to_json
|
13
|
+
end
|
14
|
+
|
3
15
|
module Slingshot
|
4
16
|
|
5
17
|
class ResultsCollectionTest < Test::Unit::TestCase
|
6
18
|
|
7
19
|
context "Collection" do
|
8
20
|
setup do
|
21
|
+
Configuration.reset :wrapper
|
9
22
|
@default_response = { 'hits' => { 'hits' => [{:_id => 1}, {:_id => 2}, {:_id => 3}] } }
|
10
23
|
end
|
11
24
|
|
@@ -26,20 +39,39 @@ module Slingshot
|
|
26
39
|
|
27
40
|
context "wrapping results" do
|
28
41
|
|
29
|
-
|
30
|
-
response = { 'hits' => { 'hits' => [ { '_id' => 1, '_source' => { :title => 'Test', :body => 'Lorem' } } ] } }
|
31
|
-
|
42
|
+
setup do
|
43
|
+
@response = { 'hits' => { 'hits' => [ { '_id' => 1, '_source' => { :title => 'Test', :body => 'Lorem' } } ] } }
|
44
|
+
end
|
45
|
+
|
46
|
+
should "wrap hits in Item by default" do
|
47
|
+
document = Results::Collection.new(@response).first
|
32
48
|
assert_kind_of Results::Item, document
|
33
49
|
assert_equal 'Test', document.title
|
34
50
|
end
|
35
51
|
|
36
|
-
should "allow access to raw underlying Hash" do
|
37
|
-
|
38
|
-
document = Results::Collection.new(response).first
|
52
|
+
should "allow access to raw underlying Hash in Item" do
|
53
|
+
document = Results::Collection.new(@response).first
|
39
54
|
assert_not_nil document[:_source][:title]
|
40
55
|
assert_equal 'Test', document[:_source][:title]
|
41
56
|
end
|
42
57
|
|
58
|
+
should "allow wrapping hits in a Hash" do
|
59
|
+
Configuration.wrapper(Hash)
|
60
|
+
|
61
|
+
document = Results::Collection.new(@response).first
|
62
|
+
assert_kind_of Hash, document
|
63
|
+
assert_raise(NoMethodError) { document.title }
|
64
|
+
assert_equal 'Test', document['_source'][:title]
|
65
|
+
end
|
66
|
+
|
67
|
+
should "allow wrapping hits in custom class" do
|
68
|
+
Configuration.wrapper(Article)
|
69
|
+
|
70
|
+
article = Results::Collection.new(@response).first
|
71
|
+
assert_kind_of Article, article
|
72
|
+
assert_equal 'Test', article.title
|
73
|
+
end
|
74
|
+
|
43
75
|
end
|
44
76
|
|
45
77
|
end
|
@@ -10,6 +10,21 @@ module Slingshot
|
|
10
10
|
@document = Results::Item.new :title => 'Test', :author => { :name => 'Kafka' }
|
11
11
|
end
|
12
12
|
|
13
|
+
should "be initialized with a Hash" do
|
14
|
+
assert_nothing_raised do
|
15
|
+
d = Results::Item.new(:id => 1)
|
16
|
+
assert_instance_of Results::Item, d
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
should "delegate non-Hash params to Hash when initializing" do
|
21
|
+
assert_nothing_raised do
|
22
|
+
d = Results::Item.new('foo')
|
23
|
+
assert_instance_of Results::Item, d
|
24
|
+
assert_equal 'foo', d[:bar] # See http://www.ruby-doc.org/core/classes/Hash.html#M000718
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
13
28
|
should "respond to :to_indexed_json" do
|
14
29
|
assert_respond_to Results::Item.new, :to_indexed_json
|
15
30
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slingshot-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Karel Minarik
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-09 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|