ripplr 0.0.6.beta → 0.0.7.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +38 -2
- data/lib/ripplr.rb +2 -1
- data/lib/ripplr/criteria.rb +59 -0
- data/lib/ripplr/indexers/ripple.rb +1 -1
- data/lib/ripplr/queryable.rb +6 -3
- data/lib/ripplr/version.rb +1 -1
- data/spec/ripplr/criteria_spec.rb +64 -0
- data/spec/ripplr/queryable_spec.rb +8 -14
- metadata +4 -1
data/README.md
CHANGED
@@ -1,2 +1,38 @@
|
|
1
|
-
Ripplr
|
2
|
-
======
|
1
|
+
Ripplr (Think Ripple/Solr)
|
2
|
+
======
|
3
|
+
Ripplr assists with indexing your Ripple documents stored in Riak. Ripplr currently supports simple full text indexing
|
4
|
+
using Riak's Solr capabilities. This will evolve to support 2i as well.
|
5
|
+
|
6
|
+
Dependencies
|
7
|
+
============
|
8
|
+
Ripplr is dependant on `ripple` and `riak-client`. Ripplr is available on RubyGems and can be installed by adding `ripplr` to your Gemfile.
|
9
|
+
|
10
|
+
It's simple to use!
|
11
|
+
===================
|
12
|
+
Once you've installed the Ripplr gem using bundler you can begin setting up your Ripple Documents to be queryable.
|
13
|
+
|
14
|
+
To make a document queryable, `include Ripplr::Queryable` and then describe which fields you would like to be queryable by using a `queryable` block.
|
15
|
+
|
16
|
+
For example you can define a class as queryable like this:
|
17
|
+
```ruby
|
18
|
+
class Wod
|
19
|
+
include Ripple::Document
|
20
|
+
include Ripplr::Queryable
|
21
|
+
property :description, String
|
22
|
+
property :notes, String
|
23
|
+
property :performed_at, Time
|
24
|
+
|
25
|
+
queryable do
|
26
|
+
text :description
|
27
|
+
text :notes
|
28
|
+
time :performed_at
|
29
|
+
end
|
30
|
+
end
|
31
|
+
```
|
32
|
+
And then create, index and search for your documents like so:
|
33
|
+
```ruby
|
34
|
+
todays_wod = Wod.create :description => 'Lawnmower 8x35lbs. Sqt Jumps 10x. Lunge Twist 20x10lbs ...', :performed_at = Time.now
|
35
|
+
todays_wod.index #add the index for your document
|
36
|
+
Wod.search(:description, "jumps") # Search WODs for descriptions that contain jump, returns an array of matching WODs
|
37
|
+
```
|
38
|
+
|
data/lib/ripplr.rb
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
module Ripplr
|
2
|
+
class Criteria
|
3
|
+
|
4
|
+
def initialize(klass, indexer=Ripplr::Indexers::Ripple)
|
5
|
+
@indexer = indexer
|
6
|
+
@target = klass
|
7
|
+
end
|
8
|
+
|
9
|
+
def where(condition)
|
10
|
+
self.condition = condition
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def each(&block)
|
15
|
+
results.each do |result|
|
16
|
+
yield result
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def size
|
21
|
+
results.size
|
22
|
+
end
|
23
|
+
alias :length :size
|
24
|
+
alias :count :size
|
25
|
+
|
26
|
+
def to_a
|
27
|
+
results
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute
|
31
|
+
return @target.list if condition.nil?
|
32
|
+
|
33
|
+
@indexer.search @target, query
|
34
|
+
end
|
35
|
+
|
36
|
+
def conditions
|
37
|
+
condition
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def results
|
42
|
+
@results ||= execute
|
43
|
+
@results
|
44
|
+
end
|
45
|
+
|
46
|
+
def condition
|
47
|
+
@condition
|
48
|
+
end
|
49
|
+
|
50
|
+
def condition=(value)
|
51
|
+
@condition = { @target.queryable_field(value.keys.first) => value.values.first }
|
52
|
+
end
|
53
|
+
|
54
|
+
def query
|
55
|
+
"#{condition.keys.first}: \"#{condition.values.first}\""
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -5,7 +5,7 @@ module Ripplr
|
|
5
5
|
::Ripple.client.index queryable_obj.bucket_name, queryable_obj.indexes_as
|
6
6
|
end
|
7
7
|
|
8
|
-
def self.search(klass, query)
|
8
|
+
def self.search(klass, query, options={})
|
9
9
|
results = ::Ripple.client.search(klass.bucket.name, query)["response"]["docs"]
|
10
10
|
results.map{|result| klass.find(result["id"])}.reject{|obj| obj.nil?}
|
11
11
|
end
|
data/lib/ripplr/queryable.rb
CHANGED
@@ -29,8 +29,12 @@ module Ripplr
|
|
29
29
|
end
|
30
30
|
|
31
31
|
module QueryableClassMethods
|
32
|
-
def
|
33
|
-
|
32
|
+
def where(condition)
|
33
|
+
Ripplr::Criteria.new(self).where condition
|
34
|
+
end
|
35
|
+
|
36
|
+
def count
|
37
|
+
self.bucket.list.size
|
34
38
|
end
|
35
39
|
|
36
40
|
def query_fields
|
@@ -54,7 +58,6 @@ module Ripplr
|
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
57
|
-
protected
|
58
61
|
def queryable_field(property_name)
|
59
62
|
matches = query_fields.select{|f| f.for? property_name}
|
60
63
|
raise Ripplr::FieldNotQueryableError.new(property_name) if matches.empty?
|
data/lib/ripplr/version.rb
CHANGED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Ripplr::Criteria do
|
4
|
+
|
5
|
+
describe "searching without a query" do
|
6
|
+
Given { Person.stub(:list).and_return [1,2,3,4,5] }
|
7
|
+
When(:results) { Ripplr::Criteria.new(Person).execute }
|
8
|
+
Then { results.should == [1,2,3,4,5] }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "searching with a query against a field" do
|
12
|
+
Given (:indexer) { mock }
|
13
|
+
Given { indexer.should_receive(:search).with(Person,"first_name_text: \"skrillex\"").and_return ["Awesome"] }
|
14
|
+
When (:results) { Ripplr::Criteria.new(Person, indexer).where(:first_name => "skrillex").execute }
|
15
|
+
Then { results.should == ["Awesome"] }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "searching with a query against a different field" do
|
19
|
+
Given (:indexer) { mock }
|
20
|
+
Given { indexer.should_receive(:search).with(Person,"last_name_text: \"Auerbach\"").and_return ["Dan"] }
|
21
|
+
When (:results) { Ripplr::Criteria.new(Person, indexer).where(:last_name => "Auerbach").execute }
|
22
|
+
Then { results.should == ["Dan"] }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "building a query with unqueryable fields" do
|
26
|
+
Then { expect { Ripplr::Criteria.new(Person).where(:bangarang => 'yes sir') }.to raise_error RuntimeError }
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "treating a criteria object like a collection executes the query" do
|
30
|
+
Given (:criteria) { Ripplr::Criteria.new(Person, indexer).where(:first_name => "Dan") }
|
31
|
+
Given (:indexer) { mock }
|
32
|
+
Given { indexer.should_receive(:search).with(Person,"first_name_text: \"Dan\"").once.and_return(["Dan"]) }
|
33
|
+
|
34
|
+
context "by calling #each" do
|
35
|
+
Given (:iterated) { Array.new }
|
36
|
+
When { criteria.each {|p| iterated << p } }
|
37
|
+
Then { iterated.should == ["Dan"] }
|
38
|
+
end
|
39
|
+
|
40
|
+
context "by calling #each twice only calls execute once" do
|
41
|
+
Given (:iterated) { Array.new }
|
42
|
+
Given { criteria.each {|p| p } }
|
43
|
+
When { criteria.each {|p| iterated << p } }
|
44
|
+
Then { iterated.should == ["Dan"] }
|
45
|
+
end
|
46
|
+
|
47
|
+
context "by calling #size" do
|
48
|
+
Then { criteria.size.should == 1 }
|
49
|
+
end
|
50
|
+
|
51
|
+
context "by calling #length" do
|
52
|
+
Then { criteria.length.should == 1 }
|
53
|
+
end
|
54
|
+
|
55
|
+
context "by calling #count" do
|
56
|
+
Then { criteria.count.should == 1 }
|
57
|
+
end
|
58
|
+
|
59
|
+
context "by calling to_a" do
|
60
|
+
Then { criteria.to_a.should == ["Dan"] }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -15,21 +15,15 @@ describe Ripplr::Queryable do
|
|
15
15
|
Then { Person.new.bucket_name.should == "people" }
|
16
16
|
end
|
17
17
|
|
18
|
-
describe "#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
When (:result) { Person.search :first_name, "Dan", indexer }
|
23
|
-
Then { result.should == [ "Dan Auerbach" ] }
|
24
|
-
end
|
25
|
-
|
26
|
-
context "when using a field that has not been defined as queryable" do
|
27
|
-
Then { expect { Person.search :full_name, "val" }.to raise_error RuntimeError }
|
28
|
-
end
|
18
|
+
describe "self#count" do
|
19
|
+
Given { Person.bucket.stub(:list).and_return [1,2,3,4,5] }
|
20
|
+
Then { Person.count.should == 5 }
|
21
|
+
end
|
29
22
|
|
30
|
-
|
31
|
-
|
32
|
-
|
23
|
+
describe "#where" do
|
24
|
+
When (:criteria) { Person.where(:first_name => "Patrick") }
|
25
|
+
Then { criteria.should be_a(Ripplr::Criteria) }
|
26
|
+
Then { criteria.conditions.should == {:first_name_text => "Patrick"} }
|
33
27
|
end
|
34
28
|
|
35
29
|
describe "#index" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ripplr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7.beta
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -70,6 +70,7 @@ extra_rdoc_files: []
|
|
70
70
|
files:
|
71
71
|
- Gemfile
|
72
72
|
- Gemfile.lock
|
73
|
+
- lib/ripplr/criteria.rb
|
73
74
|
- lib/ripplr/errors/field_not_queryable_error.rb
|
74
75
|
- lib/ripplr/errors.rb
|
75
76
|
- lib/ripplr/formatters/riak.rb
|
@@ -86,6 +87,7 @@ files:
|
|
86
87
|
- Rakefile
|
87
88
|
- README.md
|
88
89
|
- ripplr.gemspec
|
90
|
+
- spec/ripplr/criteria_spec.rb
|
89
91
|
- spec/ripplr/indexers/ripple_spec.rb
|
90
92
|
- spec/ripplr/query_field_spec.rb
|
91
93
|
- spec/ripplr/queryable_spec.rb
|
@@ -122,6 +124,7 @@ specification_version: 3
|
|
122
124
|
summary: Ripplr is a library to ease the use of Riak Search from within Rails when
|
123
125
|
using Ripple and Riak Client.
|
124
126
|
test_files:
|
127
|
+
- spec/ripplr/criteria_spec.rb
|
125
128
|
- spec/ripplr/indexers/ripple_spec.rb
|
126
129
|
- spec/ripplr/query_field_spec.rb
|
127
130
|
- spec/ripplr/queryable_spec.rb
|