elasticsearch-explain-response 0.1.0 → 0.1.1

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
  SHA1:
3
- metadata.gz: a45d429446a768356511e49f49519a4b59c82bb1
4
- data.tar.gz: cae5a22110b309224a5ad2ae74c4f1e8a0616852
3
+ metadata.gz: 5d639bb65ed9cab1fce5676ce77a1299c520cb23
4
+ data.tar.gz: 9f08ce5d4454956564f71d944d2b0dba419216c1
5
5
  SHA512:
6
- metadata.gz: 37cdde1a62667643d3e0d137457e8890251e727ba51865ac8eaf97af61ac203d66cb5c646569557e9f16eb4c784a1dc0a4297340e4327ef605f0f0904f1d927d
7
- data.tar.gz: 085fa522790f416383bed3f13c699c8c38f2f640d81a02b8948d0e022f7c2d067e052c301a20b5b72835473fa606790bb55a29c53dc317789fa1862723fd2242
6
+ metadata.gz: e39644ace8131f609212befdebb14376a1e493b6af6e876fa4a132f465b2a637a7a0380a5f4c2372c33125cc3cdc67fcdfb3b772b45040fda303d4a11570a744
7
+ data.tar.gz: 69b68ad4f1266afa383d2b6e1e9ec56942790ca6ac0f498309b3405121789a13e43f13d1fe79e694e0dc277ce3586e6bafa3786b09e3e6d0c0b701666c7993ae
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "elasticsearch-explain-response"
7
- spec.version = "0.1.0"
7
+ spec.version = "0.1.1"
8
8
  spec.authors = ["Tomoya Hirano"]
9
9
  spec.email = ["hiranotomoya@gmail.com"]
10
10
  spec.summary = %q{Parser for Elasticserach Explain response}
@@ -19,8 +19,8 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_development_dependency "bundler", "~> 1.7"
21
21
  spec.add_development_dependency "rake", "~> 10.0"
22
- spec.add_development_dependency "rspec", "~>3.2"
22
+ spec.add_development_dependency "rspec"
23
23
  spec.add_development_dependency "pry"
24
24
  spec.add_development_dependency "elasticsearch", "~> 1.0.0"
25
- spec.add_development_dependency "ansi", "~> 1.5.0"
25
+ spec.add_development_dependency "ansi"
26
26
  end
@@ -12,6 +12,16 @@ module Elasticsearch
12
12
  @field = field
13
13
  @value = value
14
14
  end
15
+
16
+ def as_json
17
+ {
18
+ type: type,
19
+ operator: operator,
20
+ operation: operation,
21
+ field: field,
22
+ value: value
23
+ }.delete_if { |k, v| v.nil? }
24
+ end
15
25
  end
16
26
  end
17
27
  end
@@ -2,9 +2,13 @@ module Elasticsearch
2
2
  module API
3
3
  module Response
4
4
  class ExplainNode
5
+ extend Forwardable
6
+
5
7
  attr_reader :score, :description, :details, :level
6
8
  attr_accessor :children
7
9
 
10
+ def_delegators :@description, :type, :operator, :operation, :field, :value
11
+
8
12
  def initialize(score:, description:, details: [], level: 0)
9
13
  @score = score
10
14
  @description = description
@@ -13,12 +17,12 @@ module Elasticsearch
13
17
  @children = []
14
18
  end
15
19
 
16
- def operator
17
- description.operator
20
+ def score_one?
21
+ score == 1.0
18
22
  end
19
23
 
20
- def type
21
- description.type
24
+ def min?
25
+ type == "min"
22
26
  end
23
27
 
24
28
  def func?
@@ -30,7 +34,7 @@ module Elasticsearch
30
34
  end
31
35
 
32
36
  def match_all?
33
- type == "match" && description.field == "*" && description.value == "*"
37
+ type == "match" && field == "*" && value == "*"
34
38
  end
35
39
 
36
40
  def boost?
@@ -40,6 +44,26 @@ module Elasticsearch
40
44
  def max_boost?
41
45
  type == "maxBoost"
42
46
  end
47
+
48
+ def func_score?
49
+ type == "func score"
50
+ end
51
+
52
+ def query_boost?
53
+ type == "queryBoost"
54
+ end
55
+
56
+ def script?
57
+ type == "script"
58
+ end
59
+
60
+ def has_children?
61
+ children.any?
62
+ end
63
+
64
+ def as_json
65
+ { score: score }.merge(description.as_json)
66
+ end
43
67
  end
44
68
  end
45
69
  end
@@ -77,6 +77,9 @@ module Elasticsearch
77
77
  /\Afunction score\, score mode \[multiply\]\z/
78
78
  type = "func score"
79
79
  operator = "x"
80
+ when /\Afunction score\, score mode \[sum\]\z/
81
+ type = "func score"
82
+ operator = "+"
80
83
  when /\Ascript score function\, computed with script:\"(?<s>.+)\"\s*(?:and parameters:\s*(?<p>.+))?/m
81
84
  type = "script"
82
85
  operation = "script"
@@ -86,6 +89,9 @@ module Elasticsearch
86
89
  param.gsub!("\n", '') if param
87
90
  field = script.scan(/doc\[\'([\w\.]+)\'\]/).flatten.uniq.compact.join(" ")
88
91
  value = [script, param].join(" ")
92
+ when /\AConstantScore\(.+\), product of\:\z/
93
+ type = "constant"
94
+ operation = "constant"
89
95
  when "static boost factor", "boostFactor"
90
96
  type = "boost"
91
97
  operation = "boost"
@@ -1,3 +1,4 @@
1
+ require "elasticsearch/api/response/renderers/hash_renderer"
1
2
  require "elasticsearch/api/response/explain_node"
2
3
  require "elasticsearch/api/response/description"
3
4
  require "elasticsearch/api/response/explain_parser"
@@ -53,6 +54,11 @@ module Elasticsearch
53
54
  @renderer.render_in_line(@root)
54
55
  end
55
56
 
57
+ def render_as_hash
58
+ parse_details
59
+ Renderers::HashRenderer.new.render(@root)
60
+ end
61
+
56
62
  private
57
63
 
58
64
  def parse_details
@@ -0,0 +1,41 @@
1
+ module Elasticsearch
2
+ module API
3
+ module Response
4
+ module Renderers
5
+ class HashRenderer
6
+ def initialize
7
+ end
8
+
9
+ def render(tree)
10
+ recursive_render(tree)
11
+ end
12
+
13
+ def recursive_render(node)
14
+ format_node(node) if node.details.any?
15
+ end
16
+
17
+ private
18
+
19
+ def format_node(node)
20
+ node.as_json.tap do |hash|
21
+ if node.has_children?
22
+ children = format_children(node, hash)
23
+ hash[:children] = children if children.any?
24
+ end
25
+ end
26
+ end
27
+
28
+ def format_children(node, hash)
29
+ node.children.map(&method(:format_node)).compact.tap do |children|
30
+ remove_dup(children, hash)
31
+ end
32
+ end
33
+
34
+ def remove_dup(collection, target)
35
+ collection.delete_if {|elm| elm == target }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -41,7 +41,7 @@ describe Elasticsearch::API::Response::ExplainResponse do
41
41
  end
42
42
 
43
43
  it "returns summary of explain in line" do
44
- expect(subject).to eq("0.05 = ((1.0(idf(2/3)) x 0.43(queryNorm)) x (1.0(tf(1.0)) x 1.0(idf(2/3)) x 0.25(fieldNorm(doc=0))) x 10.0(match(name.raw:smith)) x 0.99(func(updated_at)) x 5.93(script(popularity:\"def val = factor * log(sqrt(doc['popularity'].value) + 1) + 1\" {factor=1.0})) min 3.4e+38) x 0.5(coord(1/2)) x 1.0(queryBoost)")
44
+ expect(subject).to eq("0.05 = ((1.0(idf(2/3)) x 0.43(queryNorm)) x (1.0(tf(1.0)) x 1.0(idf(2/3)) x 0.25(fieldNorm(doc=0))) x 10.0(match(name.raw:smith)) x 0.99(func(updated_at)) x 5.93(script(popularity:\"def val = factor * log(sqrt(doc['popularity'].value) + 1) + 1\" {factor=1.0})) x 1.0(constant) min 3.4e+38) x 0.5(coord(1/2)) x 1.0(queryBoost)")
45
45
  end
46
46
 
47
47
  context "with fake_response2" do
@@ -61,7 +61,7 @@ describe Elasticsearch::API::Response::ExplainResponse do
61
61
  end
62
62
 
63
63
  it "returns summary of explain in line" do
64
- expect(subject).to eq("0.05 = ((1.0(idf(2/3)) x 0.43(queryNorm)) x (1.0(tf(1.0)) x 1.0(idf(2/3)) x 0.25(fieldNorm(doc=0))) x 10.0(match(name.raw)) x 0.99(func(updated_at)) x 5.93(script(popularity)) min 3.4e+38) x 0.5(coord(1/2)) x 1.0(queryBoost)")
64
+ expect(subject).to eq("0.05 = ((1.0(idf(2/3)) x 0.43(queryNorm)) x (1.0(tf(1.0)) x 1.0(idf(2/3)) x 0.25(fieldNorm(doc=0))) x 10.0(match(name.raw)) x 0.99(func(updated_at)) x 5.93(script(popularity)) x 1.0(constant) min 3.4e+38) x 0.5(coord(1/2)) x 1.0(queryBoost)")
65
65
  end
66
66
 
67
67
  context "with fake_response2" do
@@ -110,7 +110,7 @@ describe Elasticsearch::API::Response::ExplainResponse do
110
110
  " 0.11 = 0.11 min 3.4e+38",
111
111
  " 0.11 = 0.11(weight(_all:smith))",
112
112
  " 0.11 = 0.11(score)",
113
- " 0.11 = 0.43(queryWeight) x 0.25(fieldWeight) x 10.0 x 0.99 x 5.93(script(popularity:\"def val = factor * log(sqrt(doc['popularity'].value) + 1) + 1\" {factor=1.0}))",
113
+ " 0.11 = 0.43(queryWeight) x 0.25(fieldWeight) x 10.0 x 0.99 x 5.93(script(popularity:\"def val = factor * log(sqrt(doc['popularity'].value) + 1) + 1\" {factor=1.0})) x 1.0(constant)",
114
114
  " 0.43 = 1.0(idf(2/3)) x 0.43(queryNorm)",
115
115
  " 0.25 = 1.0(tf(1.0)) x 1.0(idf(2/3)) x 0.25(fieldNorm(doc=0))",
116
116
  " 10.0 = 10.0 x 1.0(match(name.raw:smith))",
@@ -134,6 +134,20 @@ describe Elasticsearch::API::Response::ExplainResponse do
134
134
  end
135
135
  end
136
136
 
137
+ describe "#render_as_hash" do
138
+ let(:response) do
139
+ described_class.new(fake_response["explanation"], colorize: false)
140
+ end
141
+
142
+ subject do
143
+ response.render_as_hash
144
+ end
145
+
146
+ it "returns the explain response as a hash" do
147
+ expect(subject).to be_a_kind_of(Hash)
148
+ end
149
+ end
150
+
137
151
  describe "colorization" do
138
152
  let(:response) do
139
153
  described_class.new(fake_response["explanation"])
@@ -63,6 +63,9 @@ explanation:
63
63
  description: "script score function, computed with script:\"def val\
64
64
  \ = factor * log(sqrt(doc['popularity'].value)\
65
65
  \ + 1) + 1\" and parameters: \n{factor=1.0}"
66
+ - value: 1.0
67
+ description: "ConstantScore(BooleanFilter(+BooleanFilter(+QueryWrapperFilter(name.raw:smith\
68
+ \ city:smith)) +cache(approved:T))), product of:"
66
69
  - value: 3.4028235E+38
67
70
  description: "maxBoost"
68
71
  - value: 0.5
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticsearch-explain-response
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomoya Hirano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-16 00:00:00.000000000 Z
11
+ date: 2015-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3.2'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '3.2'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: pry
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -84,16 +84,16 @@ dependencies:
84
84
  name: ansi
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 1.5.0
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: 1.5.0
96
+ version: '0'
97
97
  description: Parser for Elasticserach Explain response
98
98
  email:
99
99
  - hiranotomoya@gmail.com
@@ -115,6 +115,7 @@ files:
115
115
  - lib/elasticsearch/api/response/explain_parser.rb
116
116
  - lib/elasticsearch/api/response/explain_renderer.rb
117
117
  - lib/elasticsearch/api/response/explain_response.rb
118
+ - lib/elasticsearch/api/response/renderers/hash_renderer.rb
118
119
  - lib/elasticsearch/api/response/string_helper.rb
119
120
  - spec/elasticsearch/api/response/explain_response_spec.rb
120
121
  - spec/fixtures/response1.yml