ripplr 0.0.6.beta → 0.0.7.beta
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.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
|