daedal 0.0.4 → 0.0.5

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -1
  3. data/.travis.yml +7 -0
  4. data/Gemfile +9 -7
  5. data/Gemfile.lock +47 -32
  6. data/README.md +115 -56
  7. data/daedal.gemspec +0 -1
  8. data/lib/daedal.rb +41 -5
  9. data/lib/daedal/attributes/boost.rb +7 -0
  10. data/lib/daedal/attributes/facet.rb +13 -0
  11. data/lib/daedal/attributes/field.rb +7 -0
  12. data/lib/daedal/attributes/filter.rb +2 -2
  13. data/lib/daedal/attributes/filter_array.rb +4 -4
  14. data/lib/daedal/attributes/query.rb +2 -2
  15. data/lib/daedal/attributes/query_array.rb +2 -2
  16. data/lib/daedal/attributes/query_value.rb +19 -0
  17. data/lib/daedal/facets/facet.rb +15 -0
  18. data/lib/daedal/filters/and_filter.rb +2 -5
  19. data/lib/daedal/filters/bool_filter.rb +15 -0
  20. data/lib/daedal/filters/{base_filter.rb → filter.rb} +1 -3
  21. data/lib/daedal/filters/geo_distance_filter.rb +6 -9
  22. data/lib/daedal/filters/or_filter.rb +18 -0
  23. data/lib/daedal/filters/range_filter.rb +8 -8
  24. data/lib/daedal/filters/term_filter.rb +3 -6
  25. data/lib/daedal/filters/terms_filter.rb +3 -6
  26. data/lib/daedal/queries/bool_query.rb +8 -11
  27. data/lib/daedal/queries/constant_score_query.rb +4 -8
  28. data/lib/daedal/queries/dis_max_query.rb +5 -9
  29. data/lib/daedal/queries/filtered_query.rb +3 -8
  30. data/lib/daedal/queries/fuzzy_query.rb +24 -0
  31. data/lib/daedal/queries/match_all_query.rb +1 -3
  32. data/lib/daedal/queries/match_query.rb +11 -15
  33. data/lib/daedal/queries/multi_match_query.rb +12 -16
  34. data/lib/daedal/queries/nested_query.rb +7 -10
  35. data/lib/daedal/queries/prefix_query.rb +7 -9
  36. data/lib/daedal/queries/{base_query.rb → query.rb} +1 -4
  37. data/lib/daedal/queries/query_string_query.rb +32 -0
  38. data/lib/daedal/version.rb +1 -1
  39. data/spec/spec_helper.rb +4 -2
  40. data/spec/unit/daedal/filters/and_filter_spec.rb +0 -1
  41. data/spec/unit/daedal/filters/bool_filter_spec.rb +89 -0
  42. data/spec/unit/daedal/filters/geo_distance_filter_spec.rb +0 -1
  43. data/spec/unit/daedal/filters/or_filter_spec.rb +74 -0
  44. data/spec/unit/daedal/filters/range_filter_spec.rb +0 -1
  45. data/spec/unit/daedal/filters/term_filter_spec.rb +0 -1
  46. data/spec/unit/daedal/filters/terms_filter_spec.rb +4 -2
  47. data/spec/unit/daedal/queries/bool_query_spec.rb +1 -3
  48. data/spec/unit/daedal/queries/constant_score_query_spec.rb +0 -2
  49. data/spec/unit/daedal/queries/dis_max_query_spec.rb +1 -2
  50. data/spec/unit/daedal/queries/filtered_query_spec.rb +1 -3
  51. data/spec/unit/daedal/queries/fuzzy_query_spec.rb +89 -0
  52. data/spec/unit/daedal/queries/match_all_query_spec.rb +0 -1
  53. data/spec/unit/daedal/queries/match_query_spec.rb +2 -3
  54. data/spec/unit/daedal/queries/multi_match_query_spec.rb +2 -3
  55. data/spec/unit/daedal/queries/nested_query_spec.rb +0 -2
  56. data/spec/unit/daedal/queries/prefix_query_spec.rb +0 -1
  57. data/spec/unit/daedal/queries/query_string_spec.rb +296 -0
  58. metadata +18 -7
  59. data/lib/daedal/attributes.rb +0 -15
  60. data/lib/daedal/filters.rb +0 -11
  61. data/lib/daedal/queries.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 591b82d1a7aec22b940c410fd2d5afe79877e24f
4
- data.tar.gz: 16e8916ccff2aef76cc75f1052085ffe3d08527f
3
+ metadata.gz: c847bcafde8c2364dd1105418bf51ddb0f6ecd42
4
+ data.tar.gz: 4abb328be7b9473dec47854db2e1207cce6589e9
5
5
  SHA512:
6
- metadata.gz: f0a6a7d9a161c54625c7dffd3ed1040ba7aee46e13b960ce5caaf56b0be2afa24bfb4dbd5ab9f6b2f2d0a81ee58fa51d4db03c1f4fe324644360dfc930dca525
7
- data.tar.gz: e4bc1ce204ce207255e1ebd1c5c1311fd80744fcd323cd737fce6e5fd2ffeb7d1150700d881124576d11fb738e1056a8d16835dbd34b00548429acd432e46527
6
+ metadata.gz: 50cd4b1ab8720509f8b38a7968b2e1f3258d75c7fd79a3771ddf12390210e1d13d0afcbf72fe961d12d75eba477e719922e53cc17feca06fe6a94b51200d89b6
7
+ data.tar.gz: cab1fa56a98d7f0c3380d57af1e0a96c027235080a19ad3db38818127f610103633fb91e61169ff63ccc24c9fc1a53c406dcf96f31a11a9101872d3e6e3599d2
data/.gitignore CHANGED
@@ -11,4 +11,11 @@
11
11
  # Ignore all logfiles and tempfiles.
12
12
  /log/*.log
13
13
  /tmp
14
- *.swp
14
+ *.swp
15
+
16
+ # Ignore coverage stuff
17
+ /coverage
18
+ /.coveralls.yml
19
+
20
+ # Ignore gem builds
21
+ *.gem
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ notifications:
5
+ email:
6
+ - cas13091@gmail.com
7
+ script: "bundle exec rspec"
data/Gemfile CHANGED
@@ -1,9 +1,11 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rspec'
4
- gem 'guard'
5
- gem 'guard-rspec'
6
- gem 'require_all'
7
- gem 'fuubar'
8
- gem 'debugger'
9
- gem 'virtus', '>= 1.0.0'
3
+ gemspec
4
+
5
+ group :development, :test do
6
+ gem 'rspec'
7
+ gem 'coveralls'
8
+ gem 'guard'
9
+ gem 'guard-rspec'
10
+ gem 'fuubar'
11
+ end
@@ -1,3 +1,9 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ daedal (0.0.4)
5
+ virtus (>= 1.0.0)
6
+
1
7
  GEM
2
8
  remote: https://rubygems.org/
3
9
  specs:
@@ -5,64 +11,74 @@ GEM
5
11
  descendants_tracker (~> 0.0.1)
6
12
  ice_nine (~> 0.9)
7
13
  backports (3.3.5)
8
- coderay (1.0.9)
14
+ celluloid (0.15.2)
15
+ timers (~> 1.1.0)
16
+ coderay (1.1.0)
9
17
  coercible (0.2.0)
10
18
  backports (~> 3.0, >= 3.1.0)
11
19
  descendants_tracker (~> 0.0.1)
12
- columnize (0.3.6)
13
- debugger (1.6.2)
14
- columnize (>= 0.3.1)
15
- debugger-linecache (~> 1.2.0)
16
- debugger-ruby_core_source (~> 1.2.3)
17
- debugger-linecache (1.2.0)
18
- debugger-ruby_core_source (1.2.3)
20
+ coveralls (0.7.0)
21
+ multi_json (~> 1.3)
22
+ rest-client
23
+ simplecov (>= 0.7)
24
+ term-ansicolor
25
+ thor
19
26
  descendants_tracker (0.0.3)
20
- diff-lcs (1.2.4)
27
+ diff-lcs (1.2.5)
21
28
  equalizer (0.0.8)
22
- ffi (1.9.0)
29
+ ffi (1.9.3)
23
30
  formatador (0.2.4)
24
31
  fuubar (1.2.1)
25
32
  rspec (~> 2.0)
26
33
  rspec-instafail (~> 0.2.0)
27
34
  ruby-progressbar (~> 1.0)
28
- guard (1.8.3)
35
+ guard (2.2.4)
29
36
  formatador (>= 0.2.4)
30
- listen (~> 1.3)
31
- lumberjack (>= 1.0.2)
32
- pry (>= 0.9.10)
33
- thor (>= 0.14.6)
34
- guard-rspec (3.0.2)
35
- guard (>= 1.8)
36
- rspec (~> 2.13)
37
+ listen (~> 2.1)
38
+ lumberjack (~> 1.0)
39
+ pry (>= 0.9.12)
40
+ thor (>= 0.18.1)
41
+ guard-rspec (4.2.0)
42
+ guard (>= 2.1.1)
43
+ rspec (>= 2.14, < 4.0)
37
44
  ice_nine (0.10.0)
38
- listen (1.3.1)
45
+ listen (2.4.0)
46
+ celluloid (>= 0.15.2)
39
47
  rb-fsevent (>= 0.9.3)
40
48
  rb-inotify (>= 0.9)
41
- rb-kqueue (>= 0.2)
42
49
  lumberjack (1.0.4)
43
50
  method_source (0.8.2)
44
- pry (0.9.12.2)
45
- coderay (~> 1.0.5)
51
+ mime-types (2.0)
52
+ multi_json (1.8.2)
53
+ pry (0.9.12.4)
54
+ coderay (~> 1.0)
46
55
  method_source (~> 0.8)
47
56
  slop (~> 3.4)
48
57
  rb-fsevent (0.9.3)
49
58
  rb-inotify (0.9.2)
50
59
  ffi (>= 0.5.0)
51
- rb-kqueue (0.2.0)
52
- ffi (>= 0.5.0)
53
- require_all (1.3.1)
60
+ rest-client (1.6.7)
61
+ mime-types (>= 1.16)
54
62
  rspec (2.14.1)
55
63
  rspec-core (~> 2.14.0)
56
64
  rspec-expectations (~> 2.14.0)
57
65
  rspec-mocks (~> 2.14.0)
58
- rspec-core (2.14.5)
59
- rspec-expectations (2.14.2)
66
+ rspec-core (2.14.7)
67
+ rspec-expectations (2.14.4)
60
68
  diff-lcs (>= 1.1.3, < 2.0)
61
69
  rspec-instafail (0.2.4)
62
- rspec-mocks (2.14.3)
70
+ rspec-mocks (2.14.4)
63
71
  ruby-progressbar (1.2.0)
64
- slop (3.4.6)
72
+ simplecov (0.7.1)
73
+ multi_json (~> 1.0)
74
+ simplecov-html (~> 0.7.1)
75
+ simplecov-html (0.7.1)
76
+ slop (3.4.7)
77
+ term-ansicolor (1.2.2)
78
+ tins (~> 0.8)
65
79
  thor (0.18.1)
80
+ timers (1.1.0)
81
+ tins (0.13.1)
66
82
  virtus (1.0.0)
67
83
  axiom-types (~> 0.0.5)
68
84
  coercible (~> 0.2)
@@ -73,10 +89,9 @@ PLATFORMS
73
89
  ruby
74
90
 
75
91
  DEPENDENCIES
76
- debugger
92
+ coveralls
93
+ daedal!
77
94
  fuubar
78
95
  guard
79
96
  guard-rspec
80
- require_all
81
97
  rspec
82
- virtus (>= 1.0.0)
data/README.md CHANGED
@@ -1,79 +1,109 @@
1
1
  Daedal
2
2
  ======
3
+ [![Build Status](https://travis-ci.org/cschuch/daedal.png?branch=master)](https://travis-ci.org/cschuch/daedal)
4
+ [![Coverage Status](https://coveralls.io/repos/cschuch/daedal/badge.png)](https://coveralls.io/r/cschuch/daedal)
5
+ [![Gem Version](https://badge.fury.io/rb/daedal.png)](http://badge.fury.io/rb/daedal)
3
6
 
4
7
  This repository contains a set of Ruby classes designed to make ElasticSearch
5
- query creation simpler and easier to debug. The goal is to reproduce all
6
- components of the ElasticSearch [Query DSL](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html)
7
- to aid in the construction of complex queries. Type checking and attribute
8
+ query creation simpler and easier to debug. Type checking and attribute
8
9
  coercion are handled using [Virtus](https://github.com/solnic/virtus) to make
9
10
  it harder to construct invalid ElasticSearch queries before sending them to the server.
10
11
 
11
- The ElasticSearch Query DSL is huge! There are also a ton of different options within each
12
- component. My goal is to include as much of that functionality and flexibility as possible, but
13
- also maintain as high of test coverage as possible. That means it'll take some time for this project
14
- to reach full coverage of the Query DSL, so please feel free to contribute or be patient :)
12
+ The ElasticSearch [Query DSL](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html)
13
+ has a tremendous amount of flexibility, allowing users to finely tune their search results.
14
+ However, elaborate queries often take the form of a complex, deeply nested hash,
15
+ which can become difficult to create or traverse. By wrapping the core components of the
16
+ query DSL into Ruby objects, Daedal addresses the following issues:
17
+
18
+ * Constructing a large nested hash can be a headache, and using tools like `Hashie` may result in performance issues
19
+ * Remembering all the optional parameters each query can take, where they reside within the query structure, and what values they can take can be challenging
20
+ * Improperly structured queries, or queries with bad parameters, are hard to catch before sending to the server (and receiving an error)
21
+ * Debugging invalid queries can be a grueling task
22
+
23
+ Daedal also makes it easy to define custom queries tailored to your specific use case - you can see
24
+ a simple example at the end of the documentation.
15
25
 
16
26
  Installation
17
27
  ------------
18
28
 
29
+ From the terminal:
19
30
  ``` terminal
20
31
  $ gem install daedal
21
32
  ```
22
33
 
23
- or in your `Gemfile`
34
+ or in your `Gemfile`:
24
35
 
25
36
  ``` ruby
26
37
  gem 'daedal'
27
38
  ```
28
39
 
40
+ Then, it's as simple as including the line:
41
+
42
+ ``` ruby
43
+ require 'daedal'
44
+ ```
45
+
29
46
  Usage
30
47
  --------
31
48
 
49
+ See the [Daedal Wiki](https://github.com/cschuch/daedal/wiki) for some examples.
50
+
32
51
  ### ElasticSearch Query DSL
33
52
 
34
53
  Other Ruby packages for ElasticSearch allow you to create queries either as
35
54
  hashes or by constructing raw JSON:
36
55
 
37
56
  ``` ruby
38
- match_query = {'match' => {'foo' => {'query' => 'bar'}}}
57
+ author_query = {'match' => {'author' => {'query' => 'Beckett'}}}
39
58
  ```
40
59
 
41
- For more complicated queries, dealing with the resulting large nested hash can be
42
- frustrating. Inspired by ElasticSearch's built in
60
+ For simple queries like the example above, this works just fine. However, as queries become
61
+ more complicated, the hash can quickly take on a life of its own. Inspired by ElasticSearch's
43
62
  [Java API](http://www.elasticsearch.org/guide/en/elasticsearch/client/java-api/current/),
44
- Daedal contains Ruby classes designed to make query construction more Ruby-like.
63
+ Daedal contains Ruby classes designed to make query construction more manageable.
45
64
 
46
65
  ### Queries
47
66
 
48
- Queries are contained within the `Queries` module. You can construct query components like:
67
+ Queries are contained within the `Daedal::Queries` module. You can construct query components like:
49
68
 
50
69
  ``` ruby
51
- require 'daedal'
52
-
53
- # creates the basic match query
54
- match_query = Daedal::Queries::MatchQuery.new(field: 'foo', query: 'bar')
70
+ author_query = Daedal::Queries::MatchQuery.new(field: 'author', query: 'Beckett')
55
71
  ```
56
- Each query object has `#to_json` defined for easy conversion for use with any of the Ruby
72
+
73
+ Each query has `#to_json` defined for easy conversion for use with any of the Ruby
57
74
  ElasticSearch clients out there:
75
+
58
76
  ``` ruby
59
- match_query.to_json # => "{\"match\":{\"foo\":{\"query\":\"bar\"}}}"
77
+ author_query.to_json # => "{\"match\":{\"author\":{\"query\":\"Beckett\"}}}"
60
78
  ```
61
79
 
62
- To date (12/8/2013), I have implemented the following queries:
80
+ The benefits of using Daedal become more obvious for aggregate queries such as the `bool query`:
81
+
82
+ ``` ruby
83
+ bool_query = Daedal::Queries::BoolQuery.new(must: [author_query])
84
+ bool_query.to_json # => "{\"bool\":{\"should\":[],\"must\":[{\"match\":{\"author\":{\"query\":\"Beckett\"}}}],\"must_not\":[]}}"
85
+
86
+ lines_query = Daedal::Queries::MatchQuery.new(field: 'lines', query: "We're waiting for Godot")
87
+ bool_query.should << lines_query
88
+
89
+ bool_query.to_json # => "{\"bool\":{\"should\":[{\"match\":{\"lines\":{\"query\":\"We're waiting for Godot\"}}}],\"must\":[{\"match\":{\"author\":{\"query\":\"Beckett\"}}}],\"must_not\":[]}}"
90
+ ```
91
+
92
+ Currently, the following queries have been implemented:
63
93
  * [bool query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html)
64
94
  * [constant score query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-constant-score-query.html)
65
95
  * [dis max query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-dis-max-query.html)
66
96
  * [filtered query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-filtered-query.html)
97
+ * [fuzzy query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-fuzzy-query.html)
67
98
  * [match all query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-match-all-query.html)
68
99
  * [match query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-match-query.html)
69
100
  * [multi match query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html)
70
101
  * [nested query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html)
71
102
  * [prefix query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-prefix-query.html)
103
+ * [query string query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html)
72
104
 
73
- To be implemented next:
105
+ On deck:
74
106
  * [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
107
  * [range query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-range-query.html)
78
108
  * [regexp query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html)
79
109
  * [term query](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-term-query.html)
@@ -89,28 +119,26 @@ Queries I'm not planning on implementing at all, since they're deprecated:
89
119
 
90
120
  ### Filters
91
121
 
92
- Filters are contained within the `Filters` module. You can construct filter components
122
+ Filters are contained within the `Daedal::Filters` module. You can construct filter components
93
123
  in the same way as queries:
94
124
 
95
125
  ``` ruby
96
- require 'daedal'
97
-
98
- term_filter = Daedal::Filters::TermFilter.new(field: 'foo', term: 'bar')
126
+ term_filter = Daedal::Filters::TermFilter.new(field: 'characters', term: 'Pozzo')
99
127
 
100
- term_filter.to_json # => "{\"term\":{\"foo\":\"bar\"}}"
128
+ term_filter.to_json # => "{\"term\":{\"characters\":\"Pozzo\"}}"
101
129
  ```
102
130
 
103
- To date (12/8/2013), I have implemented the following filters:
131
+ Currently, the following filters have been implemented:
104
132
  * [and filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-and-filter.html)
133
+ * [bool filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html)
105
134
  * [geo distance filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-filter.html)
135
+ * [or filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-or-filter.html)
106
136
  * [range filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-range-filter.html)
107
137
  * [term filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-term-filter.html)
108
138
  * [terms filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-terms-filter.html)
109
139
 
110
- To be implemented next:
111
- * [bool filter](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-filter.html)
140
+ On deck:
112
141
  * [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)
114
142
 
115
143
  ### Type checking and attribute coercion
116
144
 
@@ -125,54 +153,85 @@ constant_score_query = {'constant_score' => {'boost' => 'foo', 'query' => {'matc
125
153
  would yield a server error, since the `boost` parameter must be a number.
126
154
 
127
155
  Daedal uses [Virtus](https://github.com/solnic/virtus) to perform data-type coercions.
128
- That way, invalid query parameters are surfaced at runtime, making debugging easier.
129
- The previous `constant_score_query` example in Daedal would raise an error:
156
+ Invalid query parameters are surfaced at runtime, making debugging much easier.
157
+ The previous example in Daedal would raise an error:
130
158
 
131
159
  ``` ruby
132
- match_all_query = Daedal::Queries::MatchAllQuery.new()
133
- constant_score_query = Daedal::Queries::ConstantScoreQuery.new(boost: 'foo', query: match_all_query)
160
+ match_all_query = Daedal::Queries::MatchAllQuery.new
134
161
 
162
+ constant_score_query = Daedal::Queries::ConstantScoreQuery.new(boost: 'foo', query: match_all_query)
135
163
  # Virtus::CoercionError: Failed to coerce "foo" into Float
136
164
  ```
137
165
 
138
- ### Creating your own queries
166
+ Similarly, trying to add non-queries to an aggregate query like the `bool` or `dis max` queries
167
+ will result in an error:
139
168
 
140
- Currently, I've only made it through a fraction of the entire Query DSL, but will be working to
141
- achieve complete coverage as quickly as possible. If you need to use a query that
142
- I haven't gotten to yet, or if you want to create your own more specialized queries within
143
- your own project, defining the query classes is relatively straightforward - just make
144
- your new class a sublass of the `Daedal::Queries::BaseQuery` or `Daedal::Filters::BaseFilter`
145
- classes, and define the `to_hash` method. All methods made available by including `Virtus.model` in your
146
- class will be available to you, as well.
169
+ ``` ruby
170
+ dis_max_query = Daedal::Queries::DisMaxQuery.new
171
+
172
+ dis_max_query.queries << :foo
173
+ # Virtus::CoercionError: Failed to coerce :foo into "Daedal::Queries::Query"
174
+ ```
147
175
 
148
- Example:
176
+ ### Creating custom queries
177
+
178
+ Currently, I've only made it through a fraction of the entire Query DSL, but will be adding more
179
+ as time goes by. If there's a component of the query DSL that you need that isn't implemented yet,
180
+ it's easy to define it yourself within your project (or, feel free to contribute to Daedal!).
181
+
182
+ Creating custom filters or queries tailored specifically to your use case is also pretty straightforward.
183
+ Here are some guidelines:
184
+
185
+ * Make your class inherit from `Daedal::Queries::Query` or `Daedal::Filters::Filter`
186
+ * Define the parameters for your query using [Virtus](https://github.com/solnic/virtus) attributes (**note**: `strict` coercion is being used)
187
+ * Define the `#to_hash` method
188
+
189
+ Example of a custom query:
149
190
  ``` ruby
150
- class MyQuery < Daedal::Queries::BaseQuery
191
+ class PlayQuery < Daedal::Queries::Query
151
192
 
152
- # define the attributes that you need in your query
153
- attribute :foo, String
154
- attribute :bar, String
193
+ # define the parameters that you want in your query
194
+ # if the field is optional, make sure to set required to false
195
+ attribute :author, String
196
+
197
+ attribute :characters, Array[String], required: false
198
+ attribute :title, String, required: false
199
+
200
+ def construct_query
201
+ author_query = Daedal::Queries::MatchQuery.new(field: 'author', query: author)
202
+ title_query = Daedal::Queries::MatchQuery.new(field: 'title', query: title)
203
+
204
+ full_query = Daedal::Queries::BoolQuery.new(must: [author_query], should: [title_query])
205
+ characters.each do |character|
206
+ full_query.should << Daedal::Queries::MatchQuery.new(field: 'characters', query: character)
207
+ end
208
+
209
+ full_query
210
+ end
155
211
 
156
212
  # define the to_hash method to convert for use in ElasticSearch
157
213
  def to_hash
158
- ...
214
+ construct_query.to_hash
159
215
  end
160
216
  end
217
+
218
+ play_query = PlayQuery.new(author: 'Beckett', title: 'Waiting for Godot', characters: ['Estragon', 'Vladimir'])
219
+ puts play_query.to_json # => {"bool":{"should":[{"match":{"title":{"query":"Waiting for Godot"}}},{"match":{"characters":{"query":"Estragon"}}},{"match":{"characters":{"query":"Vladimir"}}}],"must":[{"match":{"author":{"query":"Beckett"}}}],"must_not":[]}}
161
220
  ```
162
221
 
163
222
  Contributing
164
223
  -------------
165
224
 
166
- The ElasticSearch Query DSL is pretty large and includes a ton of nuance. I'm starting with the
225
+ The ElasticSearch Query DSL is pretty big and includes a ton of nuance. I'm starting with the
167
226
  most basic parts of the DSL (and the parts I use for work), so if you want to help out with the project
168
227
  to meet your needs please feel free to contribute! I just ask that you:
169
228
 
170
- * Fork the project.
171
- * Make your changes or additions.
172
- * Add tests! My goal is complete test coverage, so please take the effort to make them pretty comprehensive.
173
- * Send me a pull request.
229
+ * Fork the project
230
+ * Make your changes or additions
231
+ * Add tests! My goal is to keep Daedal a thoroughly tested project
232
+ * Send me a pull request
174
233
 
175
- Feedback or suggestions are also always welcome.
234
+ Feedback or suggestions are also always welcome!
176
235
 
177
236
  License
178
237
  -------