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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +1 -1
- data/README.md +29 -1
- data/daedal.gemspec +1 -1
- data/lib/daedal/attributes.rb +5 -0
- data/lib/daedal/attributes/distance_unit.rb +15 -0
- data/lib/daedal/attributes/filter.rb +13 -0
- data/lib/daedal/attributes/filter_array.rb +24 -0
- data/lib/daedal/attributes/lower_case_string.rb +14 -0
- data/lib/daedal/attributes/query.rb +13 -0
- data/lib/daedal/attributes/query_array.rb +2 -0
- data/lib/daedal/filters.rb +3 -0
- data/lib/daedal/filters/and_filter.rb +21 -0
- data/lib/daedal/filters/base_filter.rb +1 -1
- data/lib/daedal/filters/geo_distance_filter.rb +27 -0
- data/lib/daedal/filters/range_filter.rb +27 -0
- data/lib/daedal/queries.rb +1 -0
- data/lib/daedal/queries/bool_query.rb +5 -4
- data/lib/daedal/queries/constant_score_query.rb +2 -2
- data/lib/daedal/queries/dis_max_query.rb +3 -2
- data/lib/daedal/queries/filtered_query.rb +2 -2
- data/lib/daedal/queries/match_query.rb +2 -1
- data/lib/daedal/queries/nested_query.rb +4 -4
- data/lib/daedal/queries/prefix_query.rb +25 -0
- data/lib/daedal/version.rb +3 -0
- data/spec/unit/daedal/filters/and_filter_spec.rb +87 -0
- data/spec/unit/daedal/filters/geo_distance_filter_spec.rb +104 -0
- data/spec/unit/daedal/filters/range_filter_spec.rb +90 -0
- data/spec/unit/daedal/filters/term_filter_spec.rb +3 -3
- data/spec/unit/daedal/filters/terms_filter_spec.rb +2 -2
- data/spec/unit/daedal/queries/bool_query_spec.rb +42 -4
- data/spec/unit/daedal/queries/constant_score_query_spec.rb +3 -3
- data/spec/unit/daedal/queries/dis_max_query_spec.rb +18 -2
- data/spec/unit/daedal/queries/filtered_query_spec.rb +3 -3
- data/spec/unit/daedal/queries/match_query_spec.rb +36 -8
- data/spec/unit/daedal/queries/multi_match_query_spec.rb +8 -8
- data/spec/unit/daedal/queries/nested_query_spec.rb +4 -4
- data/spec/unit/daedal/queries/prefix_query_spec.rb +85 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 591b82d1a7aec22b940c410fd2d5afe79877e24f
|
4
|
+
data.tar.gz: 16e8916ccff2aef76cc75f1052085ffe3d08527f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0a6a7d9a161c54625c7dffd3ed1040ba7aee46e13b960ce5caaf56b0be2afa24bfb4dbd5ab9f6b2f2d0a81ee58fa51d4db03c1f4fe324644360dfc930dca525
|
7
|
+
data.tar.gz: e4bc1ce204ce207255e1ebd1c5c1311fd80744fcd323cd737fce6e5fd2ffeb7d1150700d881124576d11fb738e1056a8d16835dbd34b00548429acd432e46527
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
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'
|
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
data/lib/daedal/attributes.rb
CHANGED
@@ -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
|
data/lib/daedal/filters.rb
CHANGED
@@ -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
|
@@ -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
|
data/lib/daedal/queries.rb
CHANGED
@@ -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
|
14
|
-
attribute :must, Attributes::QueryArray
|
15
|
-
attribute :must_not, Attributes::QueryArray
|
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,
|
15
|
-
attribute :filter,
|
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
|
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,
|
13
|
-
attribute :filter,
|
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,
|
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
|
-
|
19
|
-
|
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
|