qiita-elasticsearch 0.16.0 → 0.17.0

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: 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.