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 +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +10 -0
- data/lib/qiita/elasticsearch/concerns/range_operand_includable.rb +2 -2
- data/lib/qiita/elasticsearch/date_token.rb +129 -66
- data/lib/qiita/elasticsearch/matchable_token.rb +7 -7
- data/lib/qiita/elasticsearch/query_builder.rb +5 -1
- data/lib/qiita/elasticsearch/token.rb +6 -1
- data/lib/qiita/elasticsearch/tokenizer.rb +6 -1
- data/lib/qiita/elasticsearch/version.rb +1 -1
- data/qiita-elasticsearch.gemspec +2 -1
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d6570d03729c979346948b0cc263aba403bee28
|
4
|
+
data.tar.gz: c8124642ae04a4f72ef23897b57281c854af6b0e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9fdd319e921675775c7ed2db8e3708243f2e1faaa2b254765a77e43b52dcac50eb44a3ceea3270469694b9257d87550d36764577d84d8a9ba35be00dfadbf37
|
7
|
+
data.tar.gz: 878f11a6496aa4801c732ee0bf844211eb2ed354ab90b0aa271d099f7f89a046cdff2f10d7d8519885c46cd8648d864b8a676b0c487fa2b3ce3f2cffb73b4f6b
|
data/.travis.yml
CHANGED
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
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
(?<
|
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
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
61
|
+
private
|
30
62
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
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
|
-
|
51
|
-
|
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
|
-
|
121
|
+
private
|
65
122
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
136
|
+
fail NotImplementedError
|
76
137
|
end
|
138
|
+
end
|
77
139
|
end
|
78
140
|
|
79
|
-
#
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
86
|
-
|
150
|
+
private
|
151
|
+
|
152
|
+
# @return [BaseDateExpression, nil]
|
153
|
+
def date
|
154
|
+
@date ||= select_date
|
87
155
|
end
|
88
156
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
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
|
-
|
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
|
-
"
|
32
|
-
|
33
|
-
|
34
|
-
|
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,
|
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
|
-
|
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
|
data/qiita-elasticsearch.gemspec
CHANGED
@@ -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 "
|
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.
|
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-
|
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:
|
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.
|
170
|
+
rubygems_version: 2.6.8
|
157
171
|
signing_key:
|
158
172
|
specification_version: 4
|
159
173
|
summary: Elasticsearch client helper for Qiita.
|