elastic_mini_query 0.1.0alpha → 0.1.0alpha1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f271eec6911154699bc9e116ccc4c29cde412cb499a43a2dbd18b8e218b5fe3
4
- data.tar.gz: 7970a2977db2181f16c9114583f50e0139e25c620c3461940b4188503b65c227
3
+ metadata.gz: af1ccae83d66dc5f3a266caf3e4621922e46b6a2e70e8b33b03d57f5c0f3ea3a
4
+ data.tar.gz: 92a894eba2a993afb8a1bd3beb243d5a895410462814deee25acb7da1a02fcd2
5
5
  SHA512:
6
- metadata.gz: 0bf093e28079d4b7fbfc5b27fbe5ecf60e3ec8862ff4c956953c304212f80969bdbec3e4f145adf2d016c6422706b25b15de8e225a8efc5bdd06ffc0a8ee203e
7
- data.tar.gz: 8df8b2f1d9cd1cf8cc69668cebf2bb0123b03c52840885643a6cd65878666350a94ab06e66630e82dcbe30af36c24d98629c717ba36286d0616123bf4a3c3d8d
6
+ metadata.gz: 2172439fe2606bec65b9301aaaccd44630adb6d1d37631abc00bc9793181b1ee448cb73c41946ce038dd0829cb3ede2d8c4fcdee547cb1f940fc1b0f8a70dcb8
7
+ data.tar.gz: b9d0568f4e0d9640e453d8381498ea3dc6f85a16f332be68d90ed14b2ab59a912d1d36b5483abbf44857719667093dd5c99e5836754100aabeb3d0f32b195992
@@ -1,12 +1,16 @@
1
1
  # Use the latest 2.1 version of CircleCI pipeline processing engine, see https://circleci.com/docs/2.0/configuration-reference/
2
2
  version: 2.1
3
3
 
4
+ notify:
5
+ webhooks:
6
+ - url: https://outlook.office.com/webhook/407f5d2c-7620-490d-951a-7e8a3a9b3625@d52f78ca-85da-4450-9941-ac3fee2b6af6/CircleCI/6cec7adc13ed4d3980520a3ac37fdf39/6bc44637-3745-44cb-8139-6a1269444b1e
7
+
4
8
  executors:
5
9
  base-rails:
6
10
  working_directory: /app
7
11
  docker:
8
12
  - image: mosac/rails-start:2.6.3-rails5.2.3
9
- - image: docker.elastic.co/elasticsearch/elasticsearch:7.1.1
13
+ - image: aramassa/elastic_mini_query_test:7.1.1
10
14
  environment:
11
15
  "discovery.type": "single-node"
12
16
 
@@ -15,8 +19,8 @@ jobs:
15
19
  executor: base-rails
16
20
  steps:
17
21
  - checkout
18
- - run: while ! nc -z localhost 9200; do sleep 0.1; done
19
- - run: /app/spec/es_scripts/7.x.start.sh
22
+ - run: while ! nc -z localhost 9200; do sleep 0.1; done
23
+ - run: curl -O "http://localhost:9200/_cluster/health?wait_for_status=yellow&timeout=300s"
20
24
  - run: bundle install
21
25
  - run: bundle exec rspec
22
26
 
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ /.idea
1
2
  /.bundle/
2
3
  /.yardoc
3
4
  /_yardoc/
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- elastic_mini_query (0.1.0)
4
+ elastic_mini_query (0.1.0alpha)
5
5
  faraday (~> 0.15.0, >= 0.10.0)
6
6
 
7
7
  GEM
@@ -25,6 +25,7 @@ GEM
25
25
  diff-lcs (>= 1.2.0, < 2.0)
26
26
  rspec-support (~> 3.8.0)
27
27
  rspec-support (3.8.2)
28
+ timecop (0.9.1)
28
29
 
29
30
  PLATFORMS
30
31
  ruby
@@ -34,6 +35,7 @@ DEPENDENCIES
34
35
  elastic_mini_query!
35
36
  rake (~> 10.0)
36
37
  rspec (~> 3.0)
38
+ timecop (~> 0.9)
37
39
 
38
40
  BUNDLED WITH
39
41
  1.17.2
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # ElasticMiniQuery
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/elastic_mini_query`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ TODO: Write concept.
6
4
 
7
5
  ## Installation
8
6
 
@@ -20,9 +18,57 @@ Or install it yourself as:
20
18
 
21
19
  $ gem install elastic_mini_query
22
20
 
23
- ## Usage
21
+ ## Compatibility
22
+
23
+ * elasticsearch version
24
+
25
+ |elasticsearch version| |status|
26
+ |---|---|---|
27
+ |0.90|→|not implemented|
28
+ |1.x|→|not implemented|
29
+ |2.x|→|not implemented|
30
+ |5.x|→|yet|
31
+ |6.x|→|yet|
32
+ |7.x|→|compatible|
33
+
34
+ ## Basic Usage
35
+
36
+ ### Search and Aggregation
37
+
38
+ Show [Usage.md](https://github.com/[USERNAME]/elastic_mini_query/blob/master/docs/Usage.md).
39
+
40
+ ## Supported ElasticSearch functionss
41
+
42
+ ### Search
43
+
44
+ See [ElasticSearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.1/search.html)
45
+ See [ElasticSaerch](https://www.elastic.co/guide/en/elasticsearch/reference/7.1/query-dsl.html)
46
+
47
+ |Search Type|Supported|Since|
48
+ |---|---|---|
49
+
50
+ ### Metric Aggregation
51
+
52
+ See [ElasticSearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.1/search-aggregations-metrics.html)
53
+
54
+ |Aggragation Type|Supported|Since|
55
+ |---|---|---|
56
+ |avg|Yes|0.1.0|
57
+ |min|Yes|0.1.0|
58
+ |max|Yes|0.1.0|
59
+
60
+ ### Bucket Aggregation
61
+
62
+ See [ElasticSearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.1/search-aggregations-bucket.html)
63
+
64
+ |Aggragation Type|Supported|Since|
65
+ |---|---|---|
66
+ |Date Histogram|Yes|0.1.0|
67
+ |Filter|in progress|0.1.0|
68
+ |Filters|in progress|0.1.0|
69
+ |Date Range|Yes|0.1.0|
70
+ |Histogram|Yes|0.1.0|
24
71
 
25
- TODO: Write usage instructions here
26
72
 
27
73
  ## Development
28
74
 
@@ -50,12 +96,11 @@ docker-compose -f docker-compose.yml -f docker-compose/rspec.yml run app
50
96
  docker-compose exec elasticsearch /es_scripts/7.x.start.sh
51
97
  ```
52
98
 
53
-
54
99
  See: https://www.elastic.co/guide/en/kibana/7.1/tutorial-load-dataset.html
55
100
 
56
101
  ## Contributing
57
102
 
58
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/elastic_mini_query. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
103
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Aramassa/elastic_mini_query. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
59
104
 
60
105
  ## License
61
106
 
@@ -63,4 +108,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
63
108
 
64
109
  ## Code of Conduct
65
110
 
66
- Everyone interacting in the ElasticMiniQuery project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/elastic_mini_query/blob/master/CODE_OF_CONDUCT.md).
111
+ Everyone interacting in the ElasticMiniQuery project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Aramassa/elastic_mini_query/blob/master/CODE_OF_CONDUCT.md).
data/bin/rspec CHANGED
@@ -1,14 +1,4 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
1
+ #!/usr/bin/env ruby
4
2
 
5
- RED='\033[0;31m'
6
- GREEN='\033[0;32m'
7
- YELLOW='\033[1;33m'
8
- CYAN='\033[0;36m'
9
- RESET='\033[0m'
10
-
11
- echo -e "${YELLOW}Installing bundled gem files...${RESET}"
12
- bundle install -j4 --quiet
13
- echo -e "${YELLOW}done${RESET}"
14
- bundle exec rspec
3
+ require 'rspec/core'
4
+ RSpec::Core::Runner.invoke
@@ -6,18 +6,14 @@ services:
6
6
  env_file:
7
7
  - .docker-env
8
8
  entrypoint: ""
9
- command: /bin/sh -c "bundle install && while true; do echo hello world; sleep 10; done"
9
+ command: /bin/sh -c "gem install rspec-core:3.8.1 rspec:3.8.0 && bundle install && while true; do echo hello world; sleep 10; done"
10
10
  depends_on:
11
11
  - elasticsearch
12
12
  volumes:
13
13
  - ./:/app
14
14
 
15
15
  elasticsearch:
16
- image: docker.elastic.co/elasticsearch/elasticsearch:7.1.1
17
- environment:
18
- "discovery.type": "single-node"
16
+ image: aramassa/elastic_mini_query_test:7.1.1
19
17
  ports:
20
18
  - 9200:9200
21
19
  - 9300:9300
22
- volumes:
23
- - ./spec/es_scripts:/es_scripts
@@ -7,38 +7,137 @@ class ElasticSimpleQuery < ElasticMiniQuery::Client::Base
7
7
  elastic_mini_host "http://localhost:9200"
8
8
  elastic_mini_api_key "some api key"
9
9
 
10
+ ## request all data
11
+ def get_all_docs
12
+ request do |builder|
13
+ builder.indices = "bank"
14
+ end
15
+ end
10
16
  end
11
17
 
12
- esq = ElasticSimpleQuery.new
18
+ client = ElasticSimpleQuery.new
13
19
  ```
14
20
 
15
- ## Search
21
+ ## Create Index / Mapping / Templaste
22
+
23
+ |Operation|Compatibility|
24
+ |---|---|
25
+ |Mapping|URL Only (Body not compatible)|
26
+ |Template|URL Only (Body not compatible)|
27
+ |POST to Index|Nothing|
28
+
29
+ ### Mapping
30
+
31
+ ```ruby
32
+ poster.mapping!({
33
+ properties: {
34
+ "name": {
35
+ type: "keyword"
36
+ }
37
+ }
38
+ })
39
+ ```
40
+
41
+ ### Template
42
+
43
+ ```ruby
44
+ poster.templaste!("example-tpl", ["example-*", "sample-*"], {
45
+ "name": {
46
+ type: "keyword"
47
+ },
48
+ "host_name": {
49
+ "type": "keyword"
50
+ }
51
+ }, order: 30)
52
+ ```
53
+
54
+ * options
55
+ * order : adapt priority
56
+
57
+ ### Indice
58
+
59
+ * create empty index
60
+
61
+ ```ruby
62
+ poster.empty_index!
63
+ ````
64
+
65
+ ## String Match
16
66
 
17
67
  * all columns
18
68
 
19
69
  ```ruby
20
- esq.q("hello")
70
+ build do |builder|
71
+ builder.indices = "bank"
72
+ end
21
73
  ```
22
74
 
23
75
  * specify columns
24
76
 
25
77
  ```ruby
26
- esq.q("hello", columns: ["col_a", "col_b"])
78
+ ## Single
79
+ build do |builder|
80
+ builder.indices = "bank"
81
+ builder.query.match("word", :address)
82
+ end
83
+
84
+ ## Multiple
85
+ build do |builder|
86
+ builder.indices = "bank"
87
+ builder.query.match("word", [:address, :firstname])
88
+ end
89
+ ```
90
+
91
+ * multiple words
92
+
93
+ ```ruby
94
+ ## Match any words
95
+ build do |builder|
96
+ builder.indices = "bank"
97
+ builder.query.match("word1 word2 word3").match_any
98
+ end
99
+
100
+ ## Phrase Match
101
+ build do |builder|
102
+ builder.indices = "bank"
103
+ builder.query.match("word1 word2 word3").match_phrase
104
+ end
27
105
  ```
28
106
 
29
107
  ## Aggregation
30
108
 
109
+ ### Metric Aggregations
110
+
31
111
  ```ruby
32
- esq.agg
33
- .by_date(:day, format: 'YYYY-mm-dd')
34
- .filter(...)
35
- .agg("col_a", type: [:min, :max, :avg])
112
+ build do |builder|
113
+ builder.indices = "bank"
114
+ builder.aggs.agg(:balance, [:max, :avg, :min])
115
+ end
36
116
  ```
37
117
 
118
+ ### Bucket Aggregations
119
+
120
+ #### Date Histogram
121
+
122
+ ```ruby
123
+ build do |builder|
124
+ builder.indices = "bank"
125
+ builder.aggs.agg(:balance, [:max, :avg, :min])
126
+ .date_histogram("@timestamp", :day, order: :desc, format: 'yyyy-MM-dd')
127
+ end
128
+ ```
129
+
130
+ * options
131
+
132
+ |Option|Description|Type|Value|
133
+ |---|---|---|---|
134
+ |timezone|set timezone offset for "key_as_string"|String|"+09:00"|
135
+ |order| |Symbol|:desc / :asc |
136
+
38
137
  ## fetch responses
39
138
 
40
139
  ```ruby
41
- res = esq.q("hello")
140
+ res = esq.get_all_docs.execute
42
141
  res.docs.each do |row, info|
43
142
  # data processing
44
143
  end
@@ -1 +1 @@
1
- <mxfile modified="2019-06-23T01:48:16.930Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/7.8.7 Chrome/58.0.3029.110 Electron/1.7.5 Safari/537.36" etag="JS_vDKMbjwGDAZ1HIiLU" version="10.8.0" type="device"><diagram id="pMNjfHzp7TyendTe6ShR" name="Page-1">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</diagram></mxfile>
1
+ <mxfile modified="2019-07-23T14:56:31.995Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/7.8.7 Chrome/58.0.3029.110 Electron/1.7.5 Safari/537.36" etag="pIPteGx1NaqpS_nJ3g6q" version="11.0.3" type="device"><diagram id="pMNjfHzp7TyendTe6ShR" name="Page-1">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</diagram></mxfile>
@@ -6,7 +6,7 @@ require "elastic_mini_query/version"
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "elastic_mini_query"
8
8
  spec.version = ElasticMiniQuery::VERSION
9
- spec.authors = ["Mosack"]
9
+ spec.authors = ["Aramassa"]
10
10
  spec.email = [""]
11
11
 
12
12
  spec.summary = %q{Elastic Search Simple aggregation/search Query library}
@@ -41,4 +41,5 @@ Gem::Specification.new do |spec|
41
41
  spec.add_development_dependency "bundler", "~> 1.17"
42
42
  spec.add_development_dependency "rake", "~> 10.0"
43
43
  spec.add_development_dependency "rspec", "~> 3.0"
44
+ spec.add_development_dependency "timecop", "~> 0.9"
44
45
  end
@@ -2,6 +2,8 @@ require "elastic_mini_query/version"
2
2
  require "elastic_mini_query/client/base"
3
3
  require "elastic_mini_query/query/response"
4
4
  require "elastic_mini_query/query/builder"
5
+ require "elastic_mini_query/result/error"
6
+ require "elastic_mini_query/result/error_parser"
5
7
  require "elastic_mini_query/result/raw"
6
8
  require "elastic_mini_query/result/raw_parser"
7
9
  require "elastic_mini_query/result/raw_dialect_base"
@@ -12,6 +14,12 @@ require "elastic_mini_query/result/agg_result"
12
14
 
13
15
  module ElasticMiniQuery
14
16
  class Error < StandardError; end
15
- # Your code goes here...
16
-
17
+ class ResponseError < StandardError
18
+ attr_reader :response, :error
19
+ def initialize(response)
20
+ @response = response
21
+ @error = ElasticMiniQuery::Result::Error.new(response.body, nil)
22
+ @error.parse
23
+ end
24
+ end
17
25
  end
@@ -1,46 +1,182 @@
1
1
  require_relative "http_methods"
2
+ require_relative "request_dialect_v00"
3
+ require_relative "request_dialect_v68"
2
4
 
3
5
  module ElasticMiniQuery::Client
4
6
  class Base
5
- include ::ElasticMiniQuery::Client::HttpMethods
7
+ attr_accessor :size, :track_total_hits
6
8
 
7
9
  class << self
8
10
  def elastic_mini_es_version(version)
9
- @version = version
11
+ @version = Gem::Version.create(version)
10
12
  end
11
- end
12
13
 
13
- attr_accessor :size, :track_total_hits
14
+ def elastic_mini_host(host=nil)
15
+ @host = host unless host.nil?
16
+ @host
17
+ end
18
+
19
+ def elastic_mini_api_key(key=nil)
20
+ @key = key unless key.nil?
21
+ @key
22
+ end
23
+
24
+ def request_dialector
25
+ case
26
+ when @version < Gem::Version.create("7.0")
27
+ RequestDialectV68.new
28
+ else
29
+ RequestDialectV00.new
30
+ end
31
+ end
32
+ end
14
33
 
15
34
  def initialize
16
35
  @size = 100
17
36
  @track_total_hits = true
18
37
  end
19
38
 
20
- def request
21
- b = ElasticMiniQuery::Query::Builder.new
22
- b.size = size
23
- b.track_total_hits = track_total_hits
24
- yield b
39
+ def debug!
40
+ @debug = true
41
+ self
42
+ end
25
43
 
26
- res = http_post do |req|
27
- req.url("/#{b.indices}/_search")
28
- req.body = b.to_json
29
- end
44
+ def execute
45
+ Requester.new(@b, self.class.elastic_mini_host, self.class.elastic_mini_api_key).execute(@debug)
46
+ end
30
47
 
31
- ElasticMiniQuery::Query::Response.new(ElasticMiniQuery::Result::Raw.new(res.body))
48
+ def execute!
49
+ Requester.new(@b, self.class.elastic_mini_host, self.class.elastic_mini_api_key).execute!(@debug)
32
50
  end
33
- private :request
34
51
 
35
52
  def build
36
- b = ElasticMiniQuery::Query::Builder.new
37
- yield b
38
- b
53
+ @b ||= ElasticMiniQuery::Query::Builder.new
54
+ @b.size = size
55
+ @b.track_total_hits = track_total_hits
56
+ yield @b
57
+
58
+ self
39
59
  end
40
60
  private :build
41
61
 
42
- def agg(type, name)
43
- agg(type, name)
62
+ def poster(indice, type)
63
+ ElasticMiniQuery::Client::Base::IndicePoster.new(self.class.request_dialector, self.class.elastic_mini_host, self.class.elastic_mini_api_key, indice, type)
64
+ end
65
+
66
+ class IndicePoster
67
+ include ::ElasticMiniQuery::Client::HttpMethods
68
+
69
+ def initialize(dialector, url, key, indice, type)
70
+ @dialector = dialector
71
+ @client = self.class.faraday_client(url)
72
+ @indice = indice
73
+ @type = type
74
+ @key = key
75
+ end
76
+
77
+ def empty_index!
78
+ @client.put do |req|
79
+ req.headers['Content-Type'] = 'application/json'
80
+ req.headers['Authorization'] = "ApiKey #{@key}"
81
+
82
+ url = "/#{@indice}"
83
+ req.url(url)
84
+ req.body = {}.to_json
85
+ end
86
+ end
87
+
88
+ def template!(name, patterns, properties, order: nil)
89
+ @client.put do |req|
90
+ req.headers['Content-Type'] = 'application/json'
91
+ req.headers['Authorization'] = "ApiKey #{@key}"
92
+
93
+ url = "/_template/#{name}"
94
+ body = {
95
+ "index_patterns": patterns,
96
+ "mappings": {
97
+ "properties": properties
98
+ }
99
+ }
100
+ body[:order] = order if order
101
+ req.url(url)
102
+ req.body = body.to_json
103
+ end
104
+ end
105
+
106
+ def post!(id, doc)
107
+ @client.post do |req|
108
+ req.headers['Content-Type'] = 'application/json'
109
+ req.headers['Authorization'] = "ApiKey #{@key}"
110
+
111
+ url = "/#{@indice}/#{@type}/#{id}"
112
+ url = @dialector.indice_url(@indice, @type, id)
113
+ body = doc.to_json
114
+ req.url(url)
115
+ req.body = body
116
+ end
117
+ end
118
+
119
+ def mapping!(mapping)
120
+ res = @client.put do |req|
121
+ req.headers['Content-Type'] = 'application/json'
122
+ req.headers['Authorization'] = "ApiKey #{@key}"
123
+
124
+ url = @dialector.mapping_url(@indice, @type)
125
+ body = mapping.to_json
126
+ req.url(url)
127
+ req.body = body
128
+ end
129
+
130
+ raise ElasticMiniQuery::ResponseError.new(res) unless res.status == 200
131
+
132
+ return res
133
+ end
134
+
135
+ def mapping(mapping)
136
+ begin
137
+ return mapping!(mapping)
138
+ rescue => e
139
+ return ElasticMiniQuery::Query::Response.new(ElasticMiniQuery::Result::Error.new(e.response.body, nil))
140
+ end
141
+ end
142
+ end
143
+
144
+ class Requester
145
+ include ::ElasticMiniQuery::Client::HttpMethods
146
+
147
+ def initialize(builder, url, key)
148
+ @builder = builder
149
+ @url = url
150
+ @key = key
151
+ end
152
+
153
+ def execute!(debug)
154
+ res = http_post(@url, @key) do |req|
155
+ url = "/#{@builder.indices}/_search"
156
+ body = @builder.to_json
157
+ req.url(url)
158
+ req.body = body
159
+
160
+ if debug
161
+ puts url
162
+ puts body
163
+ end
164
+ end
165
+
166
+ unless res.status == 200
167
+ raise ElasticMiniQuery::ResponseError.new(res)
168
+ end
169
+
170
+ ElasticMiniQuery::Query::Response.new(ElasticMiniQuery::Result::Raw.new(res.body, @builder.parser_keys))
171
+ end
172
+
173
+ def execute(debug)
174
+ begin
175
+ return execute!(debug)
176
+ rescue ElasticMiniQuery::ResponseError => e
177
+ return ElasticMiniQuery::Query::Response.new(ElasticMiniQuery::Result::Error.new(e.response.body, nil))
178
+ end
179
+ end
44
180
  end
45
181
  end
46
182
  end
@@ -3,18 +3,8 @@ require "faraday"
3
3
  module ElasticMiniQuery::Client
4
4
  module HttpMethods
5
5
  module ClassMethods
6
- def elastic_mini_host(host=nil)
7
- @host = host unless host.nil?
8
- @host
9
- end
10
-
11
- def elastic_mini_api_key(key=nil)
12
- @key = key unless key.nil?
13
- @key
14
- end
15
-
16
- def faraday_client
17
- Faraday.new(url: elastic_mini_host) do |conn|
6
+ def faraday_client(url)
7
+ Faraday.new(url: url) do |conn|
18
8
  conn.adapter :net_http
19
9
  end
20
10
  end
@@ -24,10 +14,10 @@ module ElasticMiniQuery::Client
24
14
  base.extend(ClassMethods)
25
15
  end
26
16
 
27
- def http_post
28
- res = self.class.faraday_client.post do |req|
17
+ def http_post(url, key)
18
+ res = self.class.faraday_client(url).post do |req|
29
19
  req.headers['Content-Type'] = 'application/json'
30
- req.headers['Authorization'] = "ApiKey #{self.class.elastic_mini_api_key}"
20
+ req.headers['Authorization'] = "ApiKey #{key}"
31
21
 
32
22
  yield req
33
23
  end
@@ -0,0 +1,14 @@
1
+ module ElasticMiniQuery
2
+ module Client
3
+ class RequestDialectV00
4
+
5
+ def indice_url(indice, type, id)
6
+ "/#{indice}/_doc/#{id}"
7
+ end
8
+
9
+ def mapping_url(indice, type)
10
+ "/#{indice}/_mapping"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module ElasticMiniQuery
2
+ module Client
3
+ class RequestDialectV68 < RequestDialectV00
4
+
5
+ def indice_url(indice, type, id)
6
+ "/#{indice}/#{type}/#{id}"
7
+ end
8
+
9
+ def mapping_url(indice, type)
10
+ "/#{indice}/_mapping/#{type}"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,22 +1,89 @@
1
1
  module ElasticMiniQuery
2
2
  module Query
3
3
  class AggBuilder
4
- def initialize(type, name)
4
+ def initialize(type)
5
+ @date_histogram = nil
5
6
  @type = type
6
- @name = name
7
+ @field = nil
8
+ @types = []
7
9
 
8
- @aggs = []
10
+ @agg = {}
11
+
12
+ @timezone_offset = nil
9
13
  end
10
14
 
11
- def agg(field, as, types)
15
+ def agg(field, types)
12
16
  types = [types] unless types.is_a?(Array)
13
- @aggs << {
17
+ @field = field
18
+ @types = types
19
+
20
+ self
21
+ end
22
+
23
+ ##
24
+ # @see https://www.elastic.co/guide/en/elasticsearch/reference/7.1/search-aggregations-bucket-datehistogram-aggregation.html
25
+ #
26
+ # @param field [String]
27
+ # @param interval [Symbol]
28
+ # @param order [Symbol]
29
+ # @param format [String]
30
+ #
31
+ def date_histogram(field, interval, order: :asc, format: nil, timezone: nil)
32
+ format = case interval
33
+ when !format.nil?
34
+ when :year then "yyyy"
35
+ when :month then "yyyy-MM"
36
+ when :day then "yyyy-MM-dd"
37
+ when :hour then "yyyy-MM-dd-HH"
38
+ when :minute then "yyyy-MM-dd-HH-mm"
39
+ end
40
+ @date_histogram = {
14
41
  field: field,
15
- as: as,
16
- types: types
42
+ interval: interval
17
43
  }
18
44
 
19
- self
45
+ @date_histogram[:order] = {_key: order} if order
46
+ @date_histogram[:format] = format if format
47
+ @date_histogram[:time_zone] = timezone if timezone
48
+ end
49
+
50
+ def parser_keys
51
+ case
52
+ when @date_histogram
53
+ return ["#{@field}_by_date", {
54
+ "buckets": %w|
55
+ key_as_string
56
+ doc_count
57
+ | + @types.map{|type| "#{@field}_#{type}"}
58
+ }]
59
+ else
60
+ return ["aggs", @types.map{|type| "#{@field}_#{type}"}]
61
+ end
62
+ end
63
+
64
+ def kv(aggs)
65
+ case
66
+ when @date_histogram
67
+ aggs["#{@field}_by_date"] = {
68
+ "date_histogram": @date_histogram,
69
+ aggs: (@types.map do |type|
70
+ ary = [
71
+ "#{@field}_#{type}",
72
+ {"#{type}": {field: @field}}
73
+ ]
74
+ ary << {time_zone: @timezone_offset} if @timezone_offset
75
+ ary
76
+ end.to_h)
77
+ }
78
+ else
79
+ @types.each do |type|
80
+ aggs["#{@field}_#{type}"] = {
81
+ "#{type}": {
82
+ "field": @field
83
+ }
84
+ }
85
+ end
86
+ end
20
87
  end
21
88
  end
22
89
  end
@@ -8,23 +8,43 @@ module ElasticMiniQuery
8
8
  attr_writer :size, :track_total_hits
9
9
  def initialize
10
10
  @searches = []
11
+ @query = nil
11
12
  @aggs = []
12
13
 
13
14
  @indice = "*"
14
15
  end
15
16
 
16
- def agg(type, name)
17
- agg = ElasticMiniQuery::Query::AggBuilder.new(type, name)
17
+ def query
18
+ @query ||= ElasticMiniQuery::Query::SearchBuilder.new
19
+ end
20
+
21
+ def aggs(type=nil)
22
+ agg = ElasticMiniQuery::Query::AggBuilder.new(type)
18
23
  @aggs << agg
19
24
 
20
25
  agg
21
26
  end
22
27
 
28
+ def parser_keys
29
+ @aggs.map(&:parser_keys).to_h
30
+ end
31
+
23
32
  def to_json
24
- {
33
+ req = {
25
34
  size: @size,
26
35
  track_total_hits: @track_total_hits
27
- }.to_json
36
+ }
37
+
38
+ if @query
39
+ req[:query] = @query.to_json
40
+ end
41
+
42
+ @aggs.each do |agg|
43
+ req[:aggs] ||= {}
44
+ agg.kv(req[:aggs])
45
+ end
46
+
47
+ req.to_json
28
48
  end
29
49
  end
30
50
  end
@@ -5,9 +5,11 @@ module ElasticMiniQuery
5
5
  class Response
6
6
  def initialize(raw)
7
7
  @raw = raw
8
- @summary, @search, @aggs = @raw.parse
8
+ @summary, @search, @aggs, @error = @raw.parse
9
9
  end
10
10
 
11
+ ##
12
+ # @return ElasticMiniQuery::Result::Summary
11
13
  def summary
12
14
  @summary
13
15
  end
@@ -19,6 +21,14 @@ module ElasticMiniQuery
19
21
  def aggs
20
22
  @aggs
21
23
  end
24
+
25
+ def error?
26
+ !@error.nil?
27
+ end
28
+
29
+ def error
30
+ @error
31
+ end
22
32
  end
23
33
  end
24
34
  end
@@ -1,7 +1,71 @@
1
1
  module ElasticMiniQuery
2
2
  module Query
3
3
  class SearchBuilder
4
+ def initialize
5
+ @match
6
+ @multi_match
7
+ @any_word = true
8
+ @phrase_match = false
4
9
 
10
+ @date_range = nil
11
+ end
12
+
13
+ ##
14
+ # @param field [String]
15
+ # @param str [String]
16
+ # ex: "now-120d/d"
17
+ def date_range(field, term_gte: nil, term_lte: nil)
18
+ @date_range = {}
19
+ @date_range["#{field}"] = {}
20
+
21
+ @date_range["#{field}"][:gte] = term_gte if term_gte
22
+ @date_range["#{field}"][:lte] = term_lte if term_lte
23
+ end
24
+
25
+ def match(word, col = nil)
26
+ case
27
+ when col.nil?
28
+ @multi_match = {
29
+ query: word,
30
+ type: "most_fields"
31
+ }
32
+ when col.is_a?(Array)
33
+ @multi_match = {
34
+ query: word,
35
+ type: "most_fields",
36
+ fields: col
37
+ }
38
+ else
39
+ @match = {}
40
+ @match[col] = word
41
+ end
42
+
43
+ self
44
+ end
45
+
46
+ def match_any(bool=true)
47
+ @any_word = bool
48
+ @phrase_match = !bool
49
+
50
+ self
51
+ end
52
+
53
+ def match_phrase(bool=true)
54
+ @phrase_match = bool
55
+ @any_word = !bool
56
+
57
+ self
58
+ end
59
+
60
+ def to_json
61
+ @multi_match[:type] = "phrase" if @phrase_match && @multi_match
62
+ query = {}
63
+ query[:match] = @match if @match
64
+ query[:multi_match] = @multi_match if @multi_match
65
+
66
+ query[:range] = @date_range if @date_range
67
+ query
68
+ end
5
69
  end
6
70
  end
7
71
  end
@@ -3,7 +3,50 @@ require "elastic_mini_query/result/agg_item"
3
3
  module ElasticMiniQuery::Result
4
4
  class AggResult
5
5
 
6
- attr_accessor :aggregations
6
+ def initialize(aggs, parser_keys)
7
+ @metrics = {}
8
+ return if aggs.nil?
9
+ @aggs = aggs
10
+
11
+ parser_keys.each do |top_field, keys|
12
+ child = top_field == "aggs" ? aggs : aggs[top_field.to_s]
13
+ @metrics[top_field] = parse_agg(child, keys, {})
14
+ end
15
+ end
16
+
17
+ def val(aggs, keys)
18
+ keys.map do |k|
19
+ v = if aggs[k].is_a?(Hash) && aggs[k].has_key?("value")
20
+ aggs[k]["value"]
21
+ else
22
+ aggs[k]
23
+ end
24
+ [k, v]
25
+ end.to_h
26
+ end
27
+
28
+ def parse_agg(aggs, keys, result)
29
+ return if keys.nil?
30
+ case keys
31
+ when Array
32
+ if aggs.is_a? Array
33
+ return aggs.map{|agg| val(agg, keys)}
34
+ else
35
+ return val(aggs, keys)
36
+ end
37
+ when Hash
38
+ keys.each do |k, v|
39
+ return parse_agg(aggs[k.to_s], v, {})
40
+ end
41
+ else
42
+
43
+ end
44
+
45
+ end
46
+
47
+ def [](key)
48
+ @metrics[key]
49
+ end
7
50
 
8
51
  def aggs(bucket)
9
52
  return @items if @items
@@ -0,0 +1,25 @@
1
+ module ElasticMiniQuery
2
+ module Result
3
+ class Error
4
+ attr_reader :type, :reason
5
+
6
+ def initialize(es_response_text, parser_keys)
7
+ @es_response_text = es_response_text
8
+ end
9
+
10
+ ##
11
+ # @param ElasticMiniQuery::Query::Response response
12
+ #
13
+ def parse
14
+ return @summary, @search, @agg unless @parse_result.nil?
15
+ @parser = ElasticMiniQuery::Result::ErrorParser.new()
16
+ @summary, @search, @agg = @parser.parse(@es_response_text)
17
+
18
+ @type = @parser.type
19
+ @reason = @parser.reason
20
+
21
+ return @summary, @search, @agg, self
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ require "json"
2
+
3
+ module ElasticMiniQuery
4
+ module Result
5
+ class ErrorParser
6
+ attr_reader :type, :reason
7
+
8
+ def initialize(version: :latest)
9
+ end
10
+
11
+ def parse(response)
12
+ @json = JSON.parse(response)
13
+
14
+ summary = ElasticMiniQuery::Result::Summary.new
15
+ summary.took = 0
16
+ summary.total_hits = 0
17
+ summary.timed_out = false
18
+ summary.total_hits_relation = "eq"
19
+
20
+ search = ElasticMiniQuery::Result::SearchResult.new
21
+ search.hits = []
22
+ search.sources = []
23
+
24
+ agg = ElasticMiniQuery::Result::AggResult.new(nil, nil)
25
+
26
+ if(@json["error"] && @json["error"]["root_cause"])
27
+ root_cause = @json["error"]["root_cause"].first
28
+ @type = root_cause["type"]
29
+ @reason = root_cause["reason"]
30
+ else
31
+ @type = @json["error"]["type"]
32
+ @reason = @json["error"]["reason"]
33
+ end
34
+
35
+ return [summary, search, agg]
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,14 +1,15 @@
1
1
  module ElasticMiniQuery
2
2
  module Result
3
3
  class Raw
4
- def initialize(es_response_text)
4
+ def initialize(es_response_text, parser_keys)
5
5
  @es_response_text = es_response_text
6
+ @parser_keys = parser_keys
6
7
  end
7
8
 
8
9
  def parse
9
10
  return @summary, @search, @agg unless @parse_result.nil?
10
11
  @parser = ElasticMiniQuery::Result::RawParser.new()
11
- @summary, @search, @agg = @parser.parse(@es_response_text)
12
+ @summary, @search, @agg = @parser.parse(@es_response_text, @parser_keys)
12
13
  end
13
14
  end
14
15
  end
@@ -7,7 +7,7 @@ module ElasticMiniQuery
7
7
  @dialector = ElasticMiniQuery::Result::RawDialectBase.dialector(version)
8
8
  end
9
9
 
10
- def parse(response)
10
+ def parse(response, parser_keys)
11
11
  @json = JSON.parse(response)
12
12
 
13
13
  summary = ElasticMiniQuery::Result::Summary.new
@@ -20,8 +20,7 @@ module ElasticMiniQuery
20
20
  search.hits = hits
21
21
  search.sources = sources
22
22
 
23
- agg = ElasticMiniQuery::Result::AggResult.new
24
- agg.aggregations = aggregations
23
+ agg = ElasticMiniQuery::Result::AggResult.new(aggregations, parser_keys)
25
24
 
26
25
  return [summary, search, agg]
27
26
  end
@@ -1,3 +1,3 @@
1
1
  module ElasticMiniQuery
2
- VERSION = "0.1.0alpha"
2
+ VERSION = "0.1.0alpha1"
3
3
  end
@@ -0,0 +1,54 @@
1
+ version: 2
2
+ jobs:
3
+ do-rspec:
4
+ working_directory: /app
5
+ docker:
6
+ - image: mosac/rails-start:2.6.3-rails5.2.3
7
+ - image: docker.elastic.co/elasticsearch/elasticsearch:7.1.1
8
+ environment:
9
+ discovery.type: single-node
10
+ steps:
11
+ - checkout
12
+ - run:
13
+ command: while ! nc -z localhost 9200; do sleep 0.1; done
14
+ - run:
15
+ command: /app/spec/es_scripts/7.x.start.sh
16
+ - run:
17
+ command: bundle install
18
+ - run:
19
+ command: bundle exec rspec
20
+ workflows:
21
+ version: 2
22
+ rspec:
23
+ jobs:
24
+ - do-rspec
25
+
26
+ # Original config.yml file:
27
+ # # Use the latest 2.1 version of CircleCI pipeline processing engine, see https://circleci.com/docs/2.0/configuration-reference/
28
+ # version: 2.1
29
+ #
30
+ # executors:
31
+ # base-rails:
32
+ # working_directory: /app
33
+ # docker:
34
+ # - image: mosac/rails-start:2.6.3-rails5.2.3
35
+ # - image: docker.elastic.co/elasticsearch/elasticsearch:7.1.1
36
+ # environment:
37
+ # \"discovery.type\": \"single-node\"
38
+ #
39
+ # jobs:
40
+ # do-rspec:
41
+ # executor: base-rails
42
+ # steps:
43
+ # - checkout
44
+ # - run: while ! nc -z localhost 9200; do sleep 0.1; done
45
+ # - run: /app/spec/es_scripts/7.x.start.sh
46
+ # - run: bundle install
47
+ # - run: bundle exec rspec
48
+ #
49
+ # # Orchestrate or schedule a set of jobs, see https://circleci.com/docs/2.0/workflows/
50
+ # workflows:
51
+ # version: 2
52
+ # rspec:
53
+ # jobs:
54
+ # - do-rspec
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastic_mini_query
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0alpha
4
+ version: 0.1.0alpha1
5
5
  platform: ruby
6
6
  authors:
7
- - Mosack
7
+ - Aramassa
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-29 00:00:00.000000000 Z
11
+ date: 2019-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -72,6 +72,20 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '3.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: timecop
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.9'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.9'
75
89
  description: ''
76
90
  email:
77
91
  - ''
@@ -101,6 +115,8 @@ files:
101
115
  - lib/elastic_mini_query.rb
102
116
  - lib/elastic_mini_query/client/base.rb
103
117
  - lib/elastic_mini_query/client/http_methods.rb
118
+ - lib/elastic_mini_query/client/request_dialect_v00.rb
119
+ - lib/elastic_mini_query/client/request_dialect_v68.rb
104
120
  - lib/elastic_mini_query/query/agg_builder.rb
105
121
  - lib/elastic_mini_query/query/builder.rb
106
122
  - lib/elastic_mini_query/query/request.rb
@@ -108,6 +124,8 @@ files:
108
124
  - lib/elastic_mini_query/query/search_builder.rb
109
125
  - lib/elastic_mini_query/result/agg_item.rb
110
126
  - lib/elastic_mini_query/result/agg_result.rb
127
+ - lib/elastic_mini_query/result/error.rb
128
+ - lib/elastic_mini_query/result/error_parser.rb
111
129
  - lib/elastic_mini_query/result/raw.rb
112
130
  - lib/elastic_mini_query/result/raw_dialect_base.rb
113
131
  - lib/elastic_mini_query/result/raw_dialect_v00.rb
@@ -117,6 +135,7 @@ files:
117
135
  - lib/elastic_mini_query/result/search_result.rb
118
136
  - lib/elastic_mini_query/result/summary.rb
119
137
  - lib/elastic_mini_query/version.rb
138
+ - process.yml
120
139
  homepage: https://github.com/Mosac/elastic_mini_query
121
140
  licenses:
122
141
  - MIT