qiita-elasticsearch 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e3d2f73e88e60c1d6b4e3b43fdbd53d8d205f55
4
- data.tar.gz: 283b4bb3a7aebe01f57e9d2973d0513244483cb9
3
+ metadata.gz: 7d6570d03729c979346948b0cc263aba403bee28
4
+ data.tar.gz: c8124642ae04a4f72ef23897b57281c854af6b0e
5
5
  SHA512:
6
- metadata.gz: 405882ddc1197902022a273cc4d196d4230b8165f6db854eb709e05aafdf206297a3a3e334aeb9f574d5cdf237c008c402464c086ec3235d9a5196410de01120
7
- data.tar.gz: 486f63464413202789ee596c9bb4ca5083d5c8c688b3b0edd27548b211d0dfcd15aba12979062baefed00c829dea57aea47ff0bf6a4587471c4cd635dd9f1356
6
+ metadata.gz: f9fdd319e921675775c7ed2db8e3708243f2e1faaa2b254765a77e43b52dcac50eb44a3ceea3270469694b9257d87550d36764577d84d8a9ba35be00dfadbf37
7
+ data.tar.gz: 878f11a6496aa4801c732ee0bf844211eb2ed354ab90b0aa271d099f7f89a046cdff2f10d7d8519885c46cd8648d864b8a676b0c487fa2b3ce3f2cffb73b4f6b
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.0.0
3
+ - 2.3.1
4
4
  env:
5
5
  global:
6
6
  secure: f904YN7iTQRLl9mDSpRat+D5/JlFmdkL+3eXP1J8fsGV2jIdcSRc/RraAryra8trhGg69nGRsWhvwI4NLW2TgnUV8FU+474JRiAOS7sPvusCW6SdTBV5k1bW1cSFlBdtmvs9v8ew0WCptSXoZU5Ew6gEmHW+2YpUAbIvNqrC8oA=
data/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
+ ## 0.17.0
2
+
3
+ * Add support for relative date expression in date fields
4
+ * Enable specifying optional query parameters in MatchableToken
5
+
1
6
  ## 0.16.0
2
7
  - Support groups filter query
3
8
 
9
+ ## 0.15.0
10
+ - Use `match` query for non-filterable `field:value` input
11
+ - Add `:all_fields` option to `QueryBuilder#initialize` to distinguish `field:value` input and non-field input including a `:`
12
+ - Rename `:matchable_fields` option to `:default_fields` in `QueryBuilder#initialize`
13
+
4
14
  ## 0.14.3
5
15
  - Use match phrase for code search
6
16
 
@@ -8,8 +8,6 @@ module Qiita
8
8
 
9
9
  RANGE_TERM_REGEXP = /\A(?<operand>\<=|\<|\>=|\>)(?<query>.*)\z/
10
10
 
11
- private
12
-
13
11
  # @return [String, nil]
14
12
  # @example Suppose @term is "created_at:>=2015-04-16"
15
13
  # range_parameter #=> "gte"
@@ -24,6 +22,8 @@ module Qiita
24
22
  range_match[:query]
25
23
  end
26
24
 
25
+ private
26
+
27
27
  def range_match
28
28
  @range_match ||= RANGE_TERM_REGEXP.match(@term) || {}
29
29
  end
@@ -8,100 +8,163 @@ module Qiita
8
8
  class DateToken < Token
9
9
  include Concerns::RangeOperandIncludable
10
10
 
11
- # @note Matches to "YYYY", "YYYY-MM" and "YYYY-MM-DD"
12
- DATE_PATTERN = /\A
13
- (?<year>\d{4})
14
- (?:
15
- -
16
- (?<month>\d{1,2})
11
+ attr_accessor :time_zone
12
+
13
+ class BaseDateExpression
14
+ FIELD_NAMES_TABLE = {
15
+ "created" => "created_at",
16
+ "updated" => "updated_at",
17
+ }
18
+
19
+ # @param [DateToken] token date token instance containing date expressions
20
+ def initialize(token)
21
+ @token = token
22
+ end
23
+
24
+ def match
25
+ @match ||= self.class::PATTERN.match(@token.range_query || @token.term)
26
+ end
27
+
28
+ def to_hash
29
+ fail NotImplementedError
30
+ end
31
+
32
+ # e.g. created:2000-01-01 -> created_at
33
+ # @return [String]
34
+ def converted_field_name
35
+ FIELD_NAMES_TABLE[@token.field_name] || @token.field_name
36
+ end
37
+ end
38
+
39
+ class AbsoluteDateExpression < BaseDateExpression
40
+ # @note Matches to "YYYY", "YYYY-MM" and "YYYY-MM-DD"
41
+ PATTERN = /\A
42
+ (?<year>\d{4})
17
43
  (?:
18
44
  -
19
- (?<day>\d{1,2})
45
+ (?<month>\d{1,2})
46
+ (?:
47
+ -
48
+ (?<day>\d{1,2})
49
+ )?
20
50
  )?
21
- )?
22
- \z/x
51
+ \z/x
23
52
 
24
- FIELD_NAMES_TABLE = {
25
- "created" => "created_at",
26
- "updated" => "updated_at",
27
- }
53
+ def to_hash
54
+ if @token.range_parameter
55
+ range_block(@token.range_parameter => @token.range_query, "time_zone" => @token.time_zone)
56
+ else
57
+ range_block("gte" => beginning_of_range.to_s, "lt" => end_of_range.to_s, "time_zone" => @token.time_zone)
58
+ end
59
+ end
28
60
 
29
- attr_writer :time_zone
61
+ private
30
62
 
31
- # @return [Hash]
32
- # @raise [InvalidQuery]
33
- def to_hash
34
- if date_match
35
- if range_parameter
36
- {
37
- "range" => {
38
- converted_field_name => {
39
- range_parameter => range_query,
40
- "time_zone" => @time_zone,
41
- }.reject do |key, value|
42
- key == "time_zone" && value.nil?
43
- end,
44
- },
63
+ def range_block(field_block)
64
+ {
65
+ "range" => {
66
+ converted_field_name => field_block.reject do |key, value|
67
+ key == "time_zone" && value.nil?
68
+ end,
45
69
  }
46
- else
70
+ }
71
+ end
72
+
73
+ # @return [Date]
74
+ def end_of_range
75
+ @end_of_range ||=
76
+ case
77
+ when match[:day]
78
+ beginning_of_range + 1.day
79
+ when match[:month]
80
+ beginning_of_range + 1.month
81
+ else
82
+ beginning_of_range + 1.year
83
+ end
84
+ end
85
+
86
+ # @return [Date]
87
+ def beginning_of_range
88
+ @beginning_of_range ||=
89
+ case
90
+ when match[:day]
91
+ Date.new(match[:year].to_i, match[:month].to_i, match[:day].to_i)
92
+ when match[:month]
93
+ Date.new(match[:year].to_i, match[:month].to_i)
94
+ else
95
+ Date.new(match[:year].to_i)
96
+ end
97
+ end
98
+ end
99
+
100
+ class RelativeDateExpression < BaseDateExpression
101
+ # @note Matches to "30d" and "30days"
102
+ PATTERN = /\A
103
+ (?<digit>\d+)
104
+ (?<type>d|y|day|days|year|years)
105
+ \z/x
106
+
107
+ def to_hash
108
+ if @token.range_parameter
47
109
  {
48
110
  "range" => {
49
111
  converted_field_name => {
50
- "gte" => beginning_of_range.to_s,
51
- "lt" => end_of_range.to_s,
52
- "time_zone" => @time_zone,
53
- }.reject do |key, value|
54
- key == "time_zone" && value.nil?
55
- end,
112
+ @token.range_parameter => relative_range_with_hours,
113
+ },
56
114
  },
57
115
  }
116
+ else
117
+ Nodes::NullNode.new.to_hash
58
118
  end
59
- else
60
- Nodes::NullNode.new.to_hash
61
119
  end
62
- end
63
120
 
64
- private
121
+ private
65
122
 
66
- # @return [Date]
67
- def beginning_of_range
68
- @beginning_of_range ||=
69
- case
70
- when date_match[:day]
71
- Date.new(date_match[:year].to_i, date_match[:month].to_i, date_match[:day].to_i)
72
- when date_match[:month]
73
- Date.new(date_match[:year].to_i, date_match[:month].to_i)
123
+ def relative_range_with_hours
124
+ @relative_range_with_hours ||=
125
+ "now-" + convert_to_hours.to_s + "h"
126
+ end
127
+
128
+ # @return [Integer]
129
+ def convert_to_hours
130
+ case match[:type]
131
+ when "d", "day", "days"
132
+ match[:digit].to_i * 24
133
+ when "y", "year", "years"
134
+ match[:digit].to_i * 24 * 365
74
135
  else
75
- Date.new(date_match[:year].to_i)
136
+ fail NotImplementedError
76
137
  end
138
+ end
77
139
  end
78
140
 
79
- # e.g. created:2000-01-01 -> created_at
80
- # @return [String]
81
- def converted_field_name
82
- FIELD_NAMES_TABLE[@field_name] || @field_name
141
+ # @return [Hash]
142
+ def to_hash
143
+ if date
144
+ date.to_hash
145
+ else
146
+ Nodes::NullNode.new.to_hash
147
+ end
83
148
  end
84
149
 
85
- def date_match
86
- @date_match ||= DATE_PATTERN.match(range_query || @term)
150
+ private
151
+
152
+ # @return [BaseDateExpression, nil]
153
+ def date
154
+ @date ||= select_date
87
155
  end
88
156
 
89
- # @return [Date]
90
- def end_of_range
91
- @end_of_range ||=
92
- case
93
- when date_match[:day]
94
- beginning_of_range + 1.day
95
- when date_match[:month]
96
- beginning_of_range + 1.month
97
- else
98
- beginning_of_range + 1.year
99
- end
157
+ def select_date
158
+ date = AbsoluteDateExpression.new(self)
159
+ return date if date.match
160
+ date = RelativeDateExpression.new(self)
161
+ return date if date.match
162
+ nil
100
163
  end
101
164
 
102
165
  # @note Override
103
166
  def has_invalid_term?
104
- !!date_match
167
+ !date
105
168
  end
106
169
  end
107
170
  end
@@ -27,14 +27,14 @@ module Qiita
27
27
 
28
28
  # @return [Hash]
29
29
  def build_multi_match_query(type: nil, boost: 1)
30
- {
31
- "multi_match" => {
32
- "boost" => boost,
33
- "fields" => matchable_fields,
34
- "query" => @term,
35
- "type" => type,
36
- },
30
+ query = {
31
+ "boost" => boost,
32
+ "fields" => matchable_fields,
33
+ "query" => @term,
34
+ "type" => type,
37
35
  }
36
+ query.merge!(options)
37
+ { "multi_match" => query }
38
38
  end
39
39
 
40
40
  def matchable_fields
@@ -12,8 +12,10 @@ module Qiita
12
12
  # @param [Array<String>, nil] hierarchal_fields
13
13
  # @param [Array<String>, nil] int_fields
14
14
  # @param [Array<String>, nil] default_fields
15
+ # @param [Hash] matchable_options
15
16
  # @param [String, nil] time_zone
16
- def initialize(all_fields: nil, date_fields: nil, downcased_fields: nil, hierarchal_fields: nil, filterable_fields: nil, int_fields: nil, default_fields: nil, time_zone: nil)
17
+ def initialize(all_fields: nil, date_fields: nil, downcased_fields: nil, hierarchal_fields: nil,
18
+ filterable_fields: nil, int_fields: nil, default_fields: nil, time_zone: nil, matchable_options: nil)
17
19
  @all_fields = all_fields
18
20
  @date_fields = date_fields
19
21
  @downcased_fields = downcased_fields
@@ -22,6 +24,7 @@ module Qiita
22
24
  @int_fields = int_fields
23
25
  @default_fields = default_fields
24
26
  @time_zone = time_zone
27
+ @matchable_options = matchable_options
25
28
  end
26
29
 
27
30
  # @param [String] query_string Raw query string
@@ -50,6 +53,7 @@ module Qiita
50
53
  int_fields: @int_fields,
51
54
  default_fields: @default_fields,
52
55
  time_zone: @time_zone,
56
+ matchable_options: @matchable_options,
53
57
  )
54
58
  end
55
59
  end
@@ -13,6 +13,9 @@ module Qiita
13
13
  # term
14
14
  attr_reader :term
15
15
 
16
+ # @return [Hash]
17
+ attr_accessor :options
18
+
16
19
  # @param [true, false] downcased True if given term must be downcased on query representation
17
20
  # @param [String, nil] field_name Field name part
18
21
  # @param [true, false] negative True if this term represents negative token (e.g. "-Perl")
@@ -20,7 +23,8 @@ module Qiita
20
23
  # @param [true, false] filter True if this term should be used as filter
21
24
  # @param [String] term Term part
22
25
  # @param [String] token_string Original entire string
23
- def initialize(downcased: nil, field_name: nil, negative: nil, quoted: nil, filter: nil, term: nil, token_string: nil)
26
+ # @param [Hash] options Optional search parameters
27
+ def initialize(downcased: nil, field_name: nil, negative: nil, quoted: nil, filter: nil, term: nil, token_string: nil, options: nil)
24
28
  @downcased = downcased
25
29
  @field_name = field_name
26
30
  @negative = negative
@@ -28,6 +32,7 @@ module Qiita
28
32
  @filter = filter
29
33
  @term = term
30
34
  @token_string = token_string
35
+ @options = options
31
36
  end
32
37
 
33
38
  # @return [true, false] True if its term must be treated with downcased
@@ -3,6 +3,7 @@ require "qiita/elasticsearch/filterable_token"
3
3
  require "qiita/elasticsearch/hierarchal_token"
4
4
  require "qiita/elasticsearch/matchable_token"
5
5
  require "qiita/elasticsearch/int_token"
6
+ require "qiita/elasticsearch/range_token"
6
7
 
7
8
  module Qiita
8
9
  module Elasticsearch
@@ -15,6 +16,7 @@ module Qiita
15
16
  DEFAULT_DEFAULT_FIELDS = []
16
17
  EXTRA_DATE_FIELDS = %w(created updated)
17
18
  EXTRA_FILTERABLE_FIELDS = %w(created is sort updated)
19
+ DEFAULT_MATCHABLE_OPTIONS = {}
18
20
 
19
21
  TOKEN_PATTERN = /
20
22
  (?<token_string>
@@ -35,14 +37,16 @@ module Qiita
35
37
  # @param [Array<String>, nil] hierarchal_fields
36
38
  # @param [Array<String>, nil] int_fields
37
39
  # @param [Array<String>, nil] default_fields
40
+ # @param [Hash] matchable_options Optional search parameters for MatchableToken
38
41
  # @param [String, nil] time_zone
39
- def initialize(all_fields: nil, date_fields: nil, downcased_fields: nil, filterable_fields: nil, hierarchal_fields: nil, int_fields: nil, default_fields: nil, time_zone: nil)
42
+ def initialize(all_fields: nil, date_fields: nil, downcased_fields: nil, filterable_fields: nil, hierarchal_fields: nil, int_fields: nil, default_fields: nil, time_zone: nil, matchable_options: nil)
40
43
  @date_fields = (date_fields || DEFAULT_DATE_FIELDS) | EXTRA_DATE_FIELDS
41
44
  @downcased_fields = downcased_fields || DEFAULT_DOWNCASED_FIELDS
42
45
  @filterable_fields = (filterable_fields || DEFAULT_FILTERABLE_FIELDS) | EXTRA_FILTERABLE_FIELDS
43
46
  @hierarchal_fields = hierarchal_fields || DEFAULT_HIERARCHAL_FIELDS
44
47
  @int_fields = int_fields || DEFAULT_INT_FIELDS
45
48
  @default_fields = default_fields || DEFAULT_DEFAULT_FIELDS
49
+ @matchable_options = matchable_options || DEFAULT_MATCHABLE_OPTIONS
46
50
  @all_fields = aggregate_all_fields(all_fields)
47
51
  @time_zone = time_zone
48
52
  end
@@ -65,6 +69,7 @@ module Qiita
65
69
  term: term,
66
70
  token_string: token_string,
67
71
  )
72
+ token.options = @matchable_options if token.is_a?(MatchableToken)
68
73
  token.default_fields = @default_fields if token.is_a?(MatchableToken)
69
74
  token.time_zone = @time_zone if token.is_a?(DateToken)
70
75
  token
@@ -1,5 +1,5 @@
1
1
  module Qiita
2
2
  module Elasticsearch
3
- VERSION = "0.16.0"
3
+ VERSION = "0.17.0"
4
4
  end
5
5
  end
@@ -16,7 +16,8 @@ Gem::Specification.new do |spec|
16
16
  spec.require_paths = ["lib"]
17
17
  spec.add_dependency "activesupport"
18
18
  spec.add_development_dependency "bundler", ">= 1.7"
19
- spec.add_development_dependency "codeclimate-test-reporter"
19
+ spec.add_development_dependency "simplecov"
20
+ spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0"
20
21
  spec.add_development_dependency "rake", "~> 10.0"
21
22
  spec.add_development_dependency "rspec", "~> 3.3"
22
23
  spec.add_development_dependency "rubocop", "0.29.1"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qiita-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-20 00:00:00.000000000 Z
11
+ date: 2016-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.7'
41
41
  - !ruby/object:Gem::Dependency
42
- name: codeclimate-test-reporter
42
+ name: simplecov
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: codeclimate-test-reporter
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -153,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
167
  version: '0'
154
168
  requirements: []
155
169
  rubyforge_project:
156
- rubygems_version: 2.4.5
170
+ rubygems_version: 2.6.8
157
171
  signing_key:
158
172
  specification_version: 4
159
173
  summary: Elasticsearch client helper for Qiita.