daedal 0.0.3 → 0.0.4

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +29 -1
  5. data/daedal.gemspec +1 -1
  6. data/lib/daedal/attributes.rb +5 -0
  7. data/lib/daedal/attributes/distance_unit.rb +15 -0
  8. data/lib/daedal/attributes/filter.rb +13 -0
  9. data/lib/daedal/attributes/filter_array.rb +24 -0
  10. data/lib/daedal/attributes/lower_case_string.rb +14 -0
  11. data/lib/daedal/attributes/query.rb +13 -0
  12. data/lib/daedal/attributes/query_array.rb +2 -0
  13. data/lib/daedal/filters.rb +3 -0
  14. data/lib/daedal/filters/and_filter.rb +21 -0
  15. data/lib/daedal/filters/base_filter.rb +1 -1
  16. data/lib/daedal/filters/geo_distance_filter.rb +27 -0
  17. data/lib/daedal/filters/range_filter.rb +27 -0
  18. data/lib/daedal/queries.rb +1 -0
  19. data/lib/daedal/queries/bool_query.rb +5 -4
  20. data/lib/daedal/queries/constant_score_query.rb +2 -2
  21. data/lib/daedal/queries/dis_max_query.rb +3 -2
  22. data/lib/daedal/queries/filtered_query.rb +2 -2
  23. data/lib/daedal/queries/match_query.rb +2 -1
  24. data/lib/daedal/queries/nested_query.rb +4 -4
  25. data/lib/daedal/queries/prefix_query.rb +25 -0
  26. data/lib/daedal/version.rb +3 -0
  27. data/spec/unit/daedal/filters/and_filter_spec.rb +87 -0
  28. data/spec/unit/daedal/filters/geo_distance_filter_spec.rb +104 -0
  29. data/spec/unit/daedal/filters/range_filter_spec.rb +90 -0
  30. data/spec/unit/daedal/filters/term_filter_spec.rb +3 -3
  31. data/spec/unit/daedal/filters/terms_filter_spec.rb +2 -2
  32. data/spec/unit/daedal/queries/bool_query_spec.rb +42 -4
  33. data/spec/unit/daedal/queries/constant_score_query_spec.rb +3 -3
  34. data/spec/unit/daedal/queries/dis_max_query_spec.rb +18 -2
  35. data/spec/unit/daedal/queries/filtered_query_spec.rb +3 -3
  36. data/spec/unit/daedal/queries/match_query_spec.rb +36 -8
  37. data/spec/unit/daedal/queries/multi_match_query_spec.rb +8 -8
  38. data/spec/unit/daedal/queries/nested_query_spec.rb +4 -4
  39. data/spec/unit/daedal/queries/prefix_query_spec.rb +85 -0
  40. metadata +17 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 01d15eb052c93f8a9dedb824873a533e876c5eee
4
- data.tar.gz: d3408e2da2b82d8c35bf1cb07330fdb62e09c547
3
+ metadata.gz: 591b82d1a7aec22b940c410fd2d5afe79877e24f
4
+ data.tar.gz: 16e8916ccff2aef76cc75f1052085ffe3d08527f
5
5
  SHA512:
6
- metadata.gz: 1d850b9dd24946209c622306d762e8aa228994de8bdb303e19a0f572b118f42d7a6ee7df0c4ca87c17d32c512ed53f68f541e13c49bf8b28037d42072626762a
7
- data.tar.gz: 3eb44d37d68e10dc6cec2c3a5a76b3cf9e146a8c612ed4628c36818aec056a45ab587f94577380a522c484bc60db3b9ad0df4c3b97a9e2bc545f92ef7e15b701
6
+ metadata.gz: f0a6a7d9a161c54625c7dffd3ed1040ba7aee46e13b960ce5caaf56b0be2afa24bfb4dbd5ab9f6b2f2d0a81ee58fa51d4db03c1f4fe324644360dfc930dca525
7
+ data.tar.gz: e4bc1ce204ce207255e1ebd1c5c1311fd80744fcd323cd737fce6e5fd2ffeb7d1150700d881124576d11fb738e1056a8d16835dbd34b00548429acd432e46527
data/Gemfile CHANGED
@@ -6,4 +6,4 @@ gem 'guard-rspec'
6
6
  gem 'require_all'
7
7
  gem 'fuubar'
8
8
  gem 'debugger'
9
- gem 'virtus', '1.0.0'
9
+ gem 'virtus', '>= 1.0.0'
data/Gemfile.lock CHANGED
@@ -79,4 +79,4 @@ DEPENDENCIES
79
79
  guard-rspec
80
80
  require_all
81
81
  rspec
82
- virtus (= 1.0.0)
82
+ virtus (>= 1.0.0)
data/README.md CHANGED
@@ -67,6 +67,25 @@ To date (12/8/2013), I have implemented the following queries:
67
67
  * [match all query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-match-all-query.html)
68
68
  * [match query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-match-query.html)
69
69
  * [multi match query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html)
70
+ * [nested query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html)
71
+ * [prefix query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-prefix-query.html)
72
+
73
+ To be implemented next:
74
+ * [function score query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html)
75
+ * [fuzzy query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-fuzzy-query.html)
76
+ * [query string query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html)
77
+ * [range query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-range-query.html)
78
+ * [regexp query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html)
79
+ * [term query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-term-query.html)
80
+ * [terms query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html)
81
+ * [wildcard query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html)
82
+
83
+ Queries I'm not planning on implementing at all, since they're deprecated:
84
+ * [custom filters score query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-custom-filters-score-query.html)
85
+ * [custom score query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-custom-score-query.html)
86
+ * [custom boost factor query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-custom-boost-factor-query.html)
87
+ * [text query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-text-query.html)
88
+
70
89
 
71
90
  ### Filters
72
91
 
@@ -82,7 +101,16 @@ term_filter.to_json # => "{\"term\":{\"foo\":\"bar\"}}"
82
101
  ```
83
102
 
84
103
  To date (12/8/2013), I have implemented the following filters:
104
+ * [and filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-and-filter.html)
105
+ * [geo distance filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-filter.html)
106
+ * [range filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-range-filter.html)
85
107
  * [term filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-term-filter.html)
108
+ * [terms filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-terms-filter.html)
109
+
110
+ To be implemented next:
111
+ * [bool filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html)
112
+ * [nested filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-nested-filter.html)
113
+ * [or filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-or-filter.html)
86
114
 
87
115
  ### Type checking and attribute coercion
88
116
 
@@ -91,7 +119,7 @@ assign an invalid value to a specific field, which would then result in
91
119
  an error response when sending the query to the server. For instance, the query:
92
120
 
93
121
  ``` ruby
94
- constant_score_query = {'constant_score' => {'boost' => 'foo', 'query': {'match_all': {}}}}
122
+ constant_score_query = {'constant_score' => {'boost' => 'foo', 'query' => {'match_all' => {}}}}
95
123
  ```
96
124
 
97
125
  would yield a server error, since the `boost` parameter must be a number.
data/daedal.gemspec CHANGED
@@ -14,5 +14,5 @@ Gem::Specification.new do |s|
14
14
  s.homepage =
15
15
  'https://github.com/cschuch/daedal'
16
16
 
17
- s.add_dependency('virtus', '~> 1.0.0')
17
+ s.add_dependency('virtus', '>= 1.0.0')
18
18
  end
@@ -2,7 +2,12 @@ require 'virtus'
2
2
  require 'daedal/attributes/operator'
3
3
  require 'daedal/attributes/match_type'
4
4
  require 'daedal/attributes/query_array'
5
+ require 'daedal/attributes/filter_array'
5
6
  require 'daedal/attributes/score_mode'
7
+ require 'daedal/attributes/lower_case_string'
8
+ require 'daedal/attributes/distance_unit'
9
+ require 'daedal/attributes/query'
10
+ require 'daedal/attributes/filter'
6
11
 
7
12
  module Daedal
8
13
  module Attributes
@@ -0,0 +1,15 @@
1
+ module Daedal
2
+ module Attributes
3
+ """Custom coercer for the type attribute"""
4
+ class DistanceUnit < Virtus::Attribute
5
+ ALLOWED_DISTANCE_UNITS = ['mi', 'km']
6
+ def coerce(value)
7
+ if value.nil? or !ALLOWED_DISTANCE_UNITS.include? value.to_s
8
+ raise Virtus::CoercionError.new(value, 'Daedal::Attributes::DistanceUnit')
9
+ end
10
+
11
+ value.to_s
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ module Daedal
2
+ module Attributes
3
+ class Filter < Virtus::Attribute
4
+ def coerce(f)
5
+ unless f.is_a? Daedal::Filters::BaseFilter or !required? && f.nil?
6
+ raise Virtus::CoercionError.new(f, 'Daedal::Filters::BaseFilter')
7
+ end
8
+
9
+ f
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ module Daedal
2
+ module Attributes
3
+ """Custom attribute for an array of queries"""
4
+ class FilterArray < Array
5
+ # override the << method so that you throw
6
+ # an error if you don't try to append a query
7
+ def <<(f)
8
+ if f.is_a? Daedal::Filters::BaseFilter
9
+ super f
10
+ else
11
+ raise Virtus::CoercionError.new(f, 'Daedal::Filters::BaseFilter')
12
+ end
13
+ end
14
+
15
+ def unshift(f)
16
+ if f.is_a? Daedal::Filters::BaseFilter
17
+ super f
18
+ else
19
+ raise Virtus::CoercionError.new(f, 'Daedal::Filters::BaseFilter')
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ module Daedal
2
+ module Attributes
3
+ """Custom coercer for the type attribute"""
4
+ class LowerCaseString < Virtus::Attribute
5
+ def coerce(value)
6
+ value = value.to_s
7
+ if value.empty?
8
+ raise Virtus::CoercionError.new(value, 'Daedal::Attributes::LowerCaseString')
9
+ end
10
+ value.downcase
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ module Daedal
2
+ module Attributes
3
+ class Query < Virtus::Attribute
4
+ def coerce(q)
5
+ unless q.is_a? Daedal::Queries::BaseQuery or !required? && q.nil?
6
+ raise Virtus::CoercionError.new(q, 'Daedal::Queries::BaseQuery')
7
+ end
8
+
9
+ q
10
+ end
11
+ end
12
+ end
13
+ end
@@ -2,8 +2,10 @@ module Daedal
2
2
  module Attributes
3
3
  """Custom attribute for an array of queries"""
4
4
  class QueryArray < Array
5
+
5
6
  # override the << method so that you throw
6
7
  # an error if you don't try to append a query
8
+
7
9
  def <<(q)
8
10
  if q.is_a? Daedal::Queries::BaseQuery
9
11
  super q
@@ -1,6 +1,9 @@
1
1
  require 'daedal/filters/base_filter'
2
2
  require 'daedal/filters/term_filter'
3
3
  require 'daedal/filters/terms_filter'
4
+ require 'daedal/filters/range_filter'
5
+ require 'daedal/filters/geo_distance_filter'
6
+ require 'daedal/filters/and_filter'
4
7
 
5
8
  module Daedal
6
9
  module Filters
@@ -0,0 +1,21 @@
1
+ require 'daedal/filters/base_filter'
2
+ require 'daedal/attributes'
3
+
4
+ module Daedal
5
+ module Filters
6
+ """Class for the basic term filter"""
7
+ class AndFilter < BaseFilter
8
+
9
+ # required attributes
10
+ attribute :filters, Attributes::FilterArray
11
+
12
+ def to_hash
13
+ unless filters.empty?
14
+ {:and => filters.map {|f| f.to_hash}}
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -6,7 +6,7 @@ module Daedal
6
6
  include Virtus.model strict: true
7
7
 
8
8
  def to_hash
9
- {}
9
+ nil
10
10
  end
11
11
 
12
12
  def to_json
@@ -0,0 +1,27 @@
1
+ require 'daedal/filters/base_filter'
2
+ require 'daedal/attributes'
3
+
4
+ module Daedal
5
+ module Filters
6
+ """Class for the basic term filter"""
7
+ class GeoDistanceFilter < BaseFilter
8
+
9
+ # required attributes
10
+ attribute :field, Symbol
11
+ attribute :lat, Float
12
+ attribute :lon, Float
13
+ attribute :distance, Float
14
+
15
+ # non required attributes
16
+ attribute :unit, Attributes::DistanceUnit, default: 'km'
17
+
18
+ def full_distance
19
+ "#{distance}#{unit}"
20
+ end
21
+
22
+ def to_hash
23
+ {geo_distance: {distance: full_distance, field => {lat: lat, lon: lon}}}
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ require 'daedal/filters/base_filter'
2
+
3
+ module Daedal
4
+ module Filters
5
+ """Class for the basic term filter"""
6
+ class RangeFilter < BaseFilter
7
+
8
+ # required attributes
9
+ attribute :field, Symbol
10
+ attribute :gte
11
+ attribute :lte
12
+ attribute :gt
13
+ attribute :lt
14
+
15
+ def initialize(options={})
16
+ super options
17
+ unless !gte.nil? or !gt.nil? or !lt.nil? or !lte.nil?
18
+ raise "Must give at least one of gte, gt, lt, or lte"
19
+ end
20
+ end
21
+
22
+ def to_hash
23
+ {range: {field => {gte: gte, lte: lte, lt: lt, gt: gt}.select {|k,v| !v.nil?}}}
24
+ end
25
+ end
26
+ end
27
+ end
@@ -7,6 +7,7 @@ require 'daedal/queries/match_all_query'
7
7
  require 'daedal/queries/match_query'
8
8
  require 'daedal/queries/multi_match_query'
9
9
  require 'daedal/queries/nested_query'
10
+ require 'daedal/queries/prefix_query'
10
11
 
11
12
  module Daedal
12
13
  module Queries
@@ -10,18 +10,19 @@ module Daedal
10
10
 
11
11
  # should, must, and must_not must be an array of queries
12
12
  # these queries must inherit from the BaseQuery class
13
- attribute :should, Attributes::QueryArray[Daedal::Queries::BaseQuery], default: Array.new
14
- attribute :must, Attributes::QueryArray[Daedal::Queries::BaseQuery], default: Array.new
15
- attribute :must_not, Attributes::QueryArray[Daedal::Queries::BaseQuery], default: Array.new
13
+ attribute :should, Attributes::QueryArray, default: Array.new
14
+ attribute :must, Attributes::QueryArray, default: Array.new
15
+ attribute :must_not, Attributes::QueryArray, default: Array.new
16
16
 
17
17
  # non required attributes
18
18
  attribute :minimum_should_match, Integer, required: false
19
19
  attribute :boost, Integer, required: false
20
20
  attribute :name, Symbol, required: false
21
+ attribute :disable_coord, Boolean, required: false
21
22
 
22
23
  def to_hash
23
24
  result = {bool: {should: should.map {|q| q.to_hash}, must: must.map {|q| q.to_hash}, must_not: must_not.map {|q| q.to_hash}}}
24
- options = {minimum_should_match: minimum_should_match, boost: boost, _name: name}
25
+ options = {minimum_should_match: minimum_should_match, boost: boost, _name: name, disable_coord: disable_coord}
25
26
  result[:bool].merge!(options.select { |k,v| !v.nil? })
26
27
 
27
28
  result
@@ -11,8 +11,8 @@ module Daedal
11
11
  attribute :boost, Float
12
12
 
13
13
  # non required attributes, but one must be required of the two
14
- attribute :query, Daedal::Queries::BaseQuery, required: false
15
- attribute :filter, Daedal::Filters::BaseFilter, required: false
14
+ attribute :query, Attributes::Query, required: false
15
+ attribute :filter, Attributes::Filter, required: false
16
16
 
17
17
  # you must require *one of* query or filter in order for this to be valid
18
18
  def initialize(options={})
@@ -8,15 +8,16 @@ module Daedal
8
8
  class DisMaxQuery < BaseQuery
9
9
 
10
10
  # required attributes
11
- attribute :queries, Attributes::QueryArray[Daedal::Queries::BaseQuery], default: Array.new
11
+ attribute :queries, Attributes::QueryArray, default: Array.new
12
12
 
13
13
  # non required attributes
14
14
  attribute :tie_breaker, Float, required: false
15
15
  attribute :boost, Integer, required: false
16
+ attribute :name, Symbol, required: false
16
17
 
17
18
  def to_hash
18
19
  result = {dis_max: {queries: queries.map {|q| q.to_hash }}}
19
- options = {tie_breaker: tie_breaker, boost: boost}
20
+ options = {tie_breaker: tie_breaker, boost: boost, _name: name}
20
21
  result[:dis_max].merge!(options.select { |k,v| !v.nil? })
21
22
 
22
23
  result
@@ -9,8 +9,8 @@ module Daedal
9
9
  class FilteredQuery < BaseQuery
10
10
 
11
11
  # required attributes
12
- attribute :query, Daedal::Queries::BaseQuery, default: Daedal::Queries::MatchAllQuery.new
13
- attribute :filter, Daedal::Filters::BaseFilter, default: Daedal::Filters::BaseFilter.new
12
+ attribute :query, Attributes::Query, default: Daedal::Queries::MatchAllQuery.new
13
+ attribute :filter, Attributes::Filter, default: Daedal::Filters::BaseFilter.new
14
14
 
15
15
  def to_hash
16
16
  {filtered: {query: query.to_hash, filter: filter.to_hash}}
@@ -19,11 +19,12 @@ module Daedal
19
19
  attribute :analyzer, Symbol, required: false
20
20
  attribute :boost, Integer, required: false
21
21
  attribute :fuzziness, Float, required: false
22
+ attribute :slop, Integer, required: false
22
23
 
23
24
  def to_hash
24
25
 
25
26
  result = {match: {field => {query: query}}}
26
- options = {minimum_should_match: minimum_should_match, cutoff_frequency: cutoff_frequency, type: type, analyzer: analyzer, boost: boost, fuzziness: fuzziness, operator: operator}
27
+ options = {minimum_should_match: minimum_should_match, cutoff_frequency: cutoff_frequency, type: type, analyzer: analyzer, boost: boost, fuzziness: fuzziness, operator: operator, slop: slop}
27
28
  result[:match][field].merge! options.select {|k,v| !v.nil?}
28
29
 
29
30
  result
@@ -8,16 +8,16 @@ module Daedal
8
8
 
9
9
  # required attributes
10
10
  attribute :path, Symbol
11
- attribute :query, Daedal::Queries::BaseQuery
11
+ attribute :query, Attributes::Query
12
12
 
13
13
  # non required attributes
14
14
  attribute :score_mode, Attributes::ScoreMode, required: false
15
+ attribute :name, Symbol, required: false
15
16
 
16
17
  def to_hash
17
18
  result = {nested: {path: path, query: query.to_hash}}
18
- unless score_mode.nil?
19
- result[:nested][:score_mode] = score_mode
20
- end
19
+ options = {score_mode: score_mode, _name: name}
20
+ result[:nested].merge!(options.select { |k,v| !v.nil? })
21
21
 
22
22
  result
23
23
  end
@@ -0,0 +1,25 @@
1
+ require 'daedal/queries/base_query'
2
+ require 'daedal/attributes'
3
+
4
+ module Daedal
5
+ module Queries
6
+ """Class for the prefix query"""
7
+ class PrefixQuery < BaseQuery
8
+
9
+ # required attributes
10
+ attribute :field, Symbol
11
+ attribute :query, Attributes::LowerCaseString
12
+
13
+ # non required attributes
14
+ attribute :boost, Float, required: false
15
+
16
+ def to_hash
17
+ result = {prefix: {field => query}}
18
+ options = {boost: boost}
19
+ result[:prefix].merge!(options.select { |k,v| !v.nil? })
20
+
21
+ result
22
+ end
23
+ end
24
+ end
25
+ end