qiita-elasticsearch 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7f70a16904b46ae70d71fd2c397a78f8252c04c0
4
+ data.tar.gz: 0da3883804dfa7142399a83ad16aa2f70a65711d
5
+ SHA512:
6
+ metadata.gz: d75c39415180eeadec234d201bcbc9707780664595895d8afca43b0321ce111248dea3c809528c0aa9ef619735bf518335790d07e407e18716a69ed008ecedfc
7
+ data.tar.gz: 84bb7676429cd15af3b5efae5601a225120b24546b85b82439d7005be41dd51b1270771faa066a6096a357950be0a5050da69a9d6a31b6742cb11d2eafc08f68
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,38 @@
1
+ Lint/UnusedBlockArgument:
2
+ Enabled: false
3
+
4
+ Lint/UnusedMethodArgument:
5
+ Enabled: false
6
+
7
+ Metrics/AbcSize:
8
+ Enabled: false
9
+
10
+ Metrics/CyclomaticComplexity:
11
+ Enabled: false
12
+
13
+ Metrics/LineLength:
14
+ Max: 120
15
+
16
+ Metrics/MethodLength:
17
+ Enabled: false
18
+
19
+ Metrics/PerceivedComplexity:
20
+ Enabled: false
21
+
22
+ Style/Documentation:
23
+ Enabled: false
24
+
25
+ Style/DoubleNegation:
26
+ Enabled: false
27
+
28
+ Style/PredicateName:
29
+ Enabled: false
30
+
31
+ Style/RegexpLiteral:
32
+ MaxSlashes: 0
33
+
34
+ Style/StringLiterals:
35
+ EnforcedStyle: double_quotes
36
+
37
+ Style/TrailingComma:
38
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ env:
5
+ global:
6
+ secure: f904YN7iTQRLl9mDSpRat+D5/JlFmdkL+3eXP1J8fsGV2jIdcSRc/RraAryra8trhGg69nGRsWhvwI4NLW2TgnUV8FU+474JRiAOS7sPvusCW6SdTBV5k1bW1cSFlBdtmvs9v8ew0WCptSXoZU5Ew6gEmHW+2YpUAbIvNqrC8oA=
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Ryo Nakamura
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # Qiita::Elasticsearch [![Build Status](https://travis-ci.org/increments/qiita-elasticsearch.svg)](https://travis-ci.org/increments/qiita-elasticsearch) [![Code Climate](https://codeclimate.com/github/increments/qiita-elasticsearch/badges/gpa.svg)](https://codeclimate.com/github/increments/qiita-elasticsearch) [![Test Coverage](https://codeclimate.com/github/increments/qiita-elasticsearch/badges/coverage.svg)](https://codeclimate.com/github/increments/qiita-elasticsearch)
2
+ Elasticsearch client helper for Qiita.
3
+
4
+ ## Usage
5
+ ```rb
6
+ query_builder = Qiita::Elasticsearch::QueryBuilder.new
7
+ #=> #<Qiita::Elasticsearch::QueryBuilder:0x007ff81e67c4d8 @filterable_fields=nil, @matchable_fields=nil>
8
+
9
+ query_builder.build("a")
10
+ #=> {"match"=>{"_all"=>"a"}}
11
+
12
+ query_builder.build("a b")
13
+ #=> {"bool"=>{"should"=>[{"match"=>{"_all"=>"a"}}, {"match"=>{"_all"=>"b"}}]}}
14
+
15
+ query_builder.build("a -b")
16
+ #=> {"bool"=>{"must_not"=>[{"match"=>{"_all"=>"b"}}], "should"=>[{"match"=>{"_all"=>"a"}}]}}
17
+
18
+ query_builder.build('"a b"')
19
+ #=> {"match_phrase"=>{"_all"=>"a b"}}
20
+
21
+ query_builder.build("a OR b")
22
+ #=> {"bool"=>{"should"=>[{"match"=>{"_all"=>"a"}}, {"match"=>{"_all"=>"b"}}]}}
23
+
24
+ ```
25
+
26
+ ### matchable_fields
27
+ ```rb
28
+ query_builder = Qiita::Elasticsearch::QueryBuilder.new(matchable_fields: ["body", "title"])
29
+ #=> #<Qiita::Elasticsearch::QueryBuilder:0x007ff81fa59168 @filterable_fields=nil, @matchable_fields=["body", "title"]>
30
+
31
+ query_builder.build("a")
32
+ #=> {"multi_match"=>{"fields"=>["body", "title"], "query"=>"a"}}
33
+ ```
34
+
35
+ ### filterable_fields
36
+ ```rb
37
+ query_builder = Qiita::Elasticsearch::QueryBuilder.new(filterable_fields: ["tag", "title"])
38
+ #=> #<Qiita::Elasticsearch::QueryBuilder:0x007ff81e2de1f0 @filterable_fields=["tag", "title"], @matchable_fields=nil>
39
+
40
+ query_builder.build("tag:a")
41
+ #=> {"filtered"=>{"filter"=>{"term"=>{"tag"=>"a"}}, "query"=>{"match_all"=>{}}}}
42
+
43
+ query_builder.build("tag:a b")
44
+ #=> {"bool"=>{"must"=>[{"filtered"=>{"filter"=>{"term"=>{"tag"=>"a"}}, "query"=>{"match_all"=>{}}}}], "should"=>[{"match"=>{"_all"=>"b"}}]}}
45
+
46
+ query_builder.build("user:a b")
47
+ #=> {"bool"=>{"should"=>[{"match"=>{"_all"=>"user:a"}}, {"match"=>{"_all"=>"b"}}]}}
48
+ ```
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "rubocop/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new(:style)
7
+ task default: [:spec, :style]
@@ -0,0 +1,2 @@
1
+ require "qiita/elasticsearch/query_builder"
2
+ require "qiita/elasticsearch/version"
@@ -0,0 +1,83 @@
1
+ require "qiita/elasticsearch/nodes/token_node"
2
+
3
+ module Qiita
4
+ module Elasticsearch
5
+ module Nodes
6
+ class BoolQueryNode
7
+ # @param [Array<Qiita::Elasticsearch::Tokens>] tokens
8
+ # @param [Array<String>, nil] matchable_fields
9
+ def initialize(tokens, matchable_fields: nil)
10
+ @matchable_fields = matchable_fields
11
+ @tokens = tokens
12
+ end
13
+
14
+ def to_hash
15
+ case
16
+ when has_only_one_should_token?
17
+ should_query
18
+ when has_only_one_must_token?
19
+ must_query
20
+ else
21
+ {
22
+ "bool" => {
23
+ "must" => must_queries,
24
+ "must_not" => must_not_queries,
25
+ "should" => should_queries,
26
+ }.reject do |key, value|
27
+ value.empty?
28
+ end,
29
+ }
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def has_only_one_must_token?
36
+ must_not_tokens.empty? && should_tokens.empty? && must_tokens.size == 1
37
+ end
38
+
39
+ def has_only_one_should_token?
40
+ must_not_tokens.empty? && must_tokens.empty? && should_tokens.size == 1
41
+ end
42
+
43
+ def must_not_queries
44
+ must_not_tokens.map do |token|
45
+ Nodes::TokenNode.new(token, matchable_fields: @matchable_fields).to_hash
46
+ end
47
+ end
48
+
49
+ def must_not_tokens
50
+ @must_not_tokens ||= @tokens.select(&:must_not?)
51
+ end
52
+
53
+ def must_query
54
+ Nodes::TokenNode.new(must_tokens.first, matchable_fields: @matchable_fields).to_hash
55
+ end
56
+
57
+ def must_queries
58
+ must_tokens.map do |token|
59
+ Nodes::TokenNode.new(token, matchable_fields: @matchable_fields).to_hash
60
+ end
61
+ end
62
+
63
+ def must_tokens
64
+ @must_tokens ||= @tokens.select(&:must?)
65
+ end
66
+
67
+ def should_query
68
+ Nodes::TokenNode.new(should_tokens.first, matchable_fields: @matchable_fields).to_hash
69
+ end
70
+
71
+ def should_queries
72
+ should_tokens.map do |token|
73
+ Nodes::TokenNode.new(token, matchable_fields: @matchable_fields).to_hash
74
+ end
75
+ end
76
+
77
+ def should_tokens
78
+ @should_tokens ||= @tokens.select(&:should?)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,28 @@
1
+ module Qiita
2
+ module Elasticsearch
3
+ module Nodes
4
+ class FilterQueryNode
5
+ # @param [Qiita::Elasticsearch::Token] token
6
+ def initialize(token)
7
+ @token = token
8
+ end
9
+
10
+ # @return [Hash]
11
+ def to_hash
12
+ {
13
+ "filtered" => {
14
+ "filter" => {
15
+ "term" => {
16
+ @token.field_name => @token.term,
17
+ },
18
+ },
19
+ "query" => {
20
+ "match_all" => {},
21
+ },
22
+ },
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ module Qiita
2
+ module Elasticsearch
3
+ module Nodes
4
+ class MatchQueryNode
5
+ # @param [Qiita::Elasticsearch::Token] token
6
+ # @param [Array<String>, nil] matchable_fields
7
+ def initialize(token, matchable_fields: nil)
8
+ @matchable_fields = matchable_fields
9
+ @token = token
10
+ end
11
+
12
+ # @return [Hash] match query or multi_match query
13
+ def to_hash
14
+ if @matchable_fields.nil?
15
+ {
16
+ @token.quoted? ? "match_phrase" : "match" => {
17
+ "_all" => @token.term,
18
+ }
19
+ }
20
+ else
21
+ hash = {
22
+ "multi_match" => {
23
+ "fields" => @matchable_fields,
24
+ "query" => @token.term,
25
+ },
26
+ }
27
+ hash["multi_match"]["type"] = "phrase" if @token.quoted?
28
+ hash
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ module Qiita
2
+ module Elasticsearch
3
+ module Nodes
4
+ class NullNode
5
+ def to_hash
6
+ {
7
+ "query" => {
8
+ "ids" => {
9
+ "values" => [],
10
+ },
11
+ },
12
+ }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,53 @@
1
+ require "qiita/elasticsearch/nodes/bool_query_node"
2
+ require "qiita/elasticsearch/nodes/null_node"
3
+
4
+ module Qiita
5
+ module Elasticsearch
6
+ module Nodes
7
+ class OrSeparatableNode
8
+ # @param [Array<Qiita::Elasticsearch::Tokens>] tokens
9
+ # @param [Array<String>, nil] matchable_fields
10
+ def initialize(tokens, matchable_fields: nil)
11
+ @matchable_fields = matchable_fields
12
+ @tokens = tokens
13
+ end
14
+
15
+ def to_hash
16
+ case tokens_grouped_by_or_token.size
17
+ when 0
18
+ Nodes::NullNode.new.to_hash
19
+ when 1
20
+ Nodes::BoolQueryNode.new(
21
+ tokens_grouped_by_or_token.first,
22
+ matchable_fields: @matchable_fields,
23
+ ).to_hash
24
+ else
25
+ {
26
+ "bool" => {
27
+ "should" => tokens_grouped_by_or_token.map do |tokens|
28
+ Nodes::BoolQueryNode.new(
29
+ tokens,
30
+ matchable_fields: @matchable_fields,
31
+ ).to_hash
32
+ end,
33
+ },
34
+ }
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ # @return [Array<Array<Qiita::Elasticsearch::Token>>]
41
+ def tokens_grouped_by_or_token
42
+ @tokens_grouped_by_or_token ||= @tokens.each_with_object([[]]) do |token, groups|
43
+ if token.or?
44
+ groups << []
45
+ else
46
+ groups.last << token
47
+ end
48
+ end.reject(&:empty?)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,25 @@
1
+ require "qiita/elasticsearch/nodes/filter_query_node"
2
+ require "qiita/elasticsearch/nodes/match_query_node"
3
+
4
+ module Qiita
5
+ module Elasticsearch
6
+ module Nodes
7
+ class TokenNode
8
+ # @param [Qiita::Elasticsearch::Token] token
9
+ # @param [Array<String>, nil] matchable_fields
10
+ def initialize(token, matchable_fields: nil)
11
+ @matchable_fields = matchable_fields
12
+ @token = token
13
+ end
14
+
15
+ def to_hash
16
+ if @token.field_name
17
+ FilterQueryNode.new(@token).to_hash
18
+ else
19
+ MatchQueryNode.new(@token, matchable_fields: @matchable_fields).to_hash
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ require "qiita/elasticsearch/tokenizer"
2
+
3
+ module Qiita
4
+ module Elasticsearch
5
+ class Parser
6
+ # @param [Array<String>, nil] filterable_fields
7
+ def initialize(filterable_fields: nil)
8
+ @filterable_fields = filterable_fields
9
+ end
10
+
11
+ # @param [String] query_string Raw query string
12
+ # @return [Array<Qiita::Elasticsearch::Token>]
13
+ def parse(query_string)
14
+ tokenizer.tokenize(query_string)
15
+ end
16
+
17
+ private
18
+
19
+ def tokenizer
20
+ @tokenizer ||= Tokenizer.new(filterable_fields: @filterable_fields)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ require "qiita/elasticsearch/nodes/null_node"
2
+ require "qiita/elasticsearch/nodes/or_separatable_node"
3
+ require "qiita/elasticsearch/parser"
4
+
5
+ module Qiita
6
+ module Elasticsearch
7
+ class QueryBuilder
8
+ # @param [Array<String>, nil] matchable_fields
9
+ # @param [Array<String>, nil] filterable_fields
10
+ def initialize(matchable_fields: nil, filterable_fields: nil)
11
+ @matchable_fields = matchable_fields
12
+ @filterable_fields = filterable_fields
13
+ end
14
+
15
+ # @param [String] query_string Raw query string
16
+ # @return [Hash]
17
+ def build(query_string)
18
+ tokens = parser.parse(query_string)
19
+ if tokens.size.zero?
20
+ Nodes::NullNode.new.to_hash
21
+ else
22
+ Nodes::OrSeparatableNode.new(
23
+ tokens,
24
+ matchable_fields: @matchable_fields,
25
+ ).to_hash
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def parser
32
+ @parser ||= Parser.new(filterable_fields: @filterable_fields)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,56 @@
1
+ module Qiita
2
+ module Elasticsearch
3
+ class Token
4
+ attr_reader :field_name, :term
5
+
6
+ def initialize(field_name: nil, minus: nil, quoted: nil, term: nil, token_string: nil)
7
+ @field_name = field_name
8
+ @minus = minus
9
+ @quoted = quoted
10
+ @term = term
11
+ @token_string = token_string
12
+ end
13
+
14
+ def must?
15
+ !field_name.nil?
16
+ end
17
+
18
+ def must_not?
19
+ negative?
20
+ end
21
+
22
+ # @return [true, false] True if this token is for negative filter
23
+ # @note `Ruby -Perl`
24
+ # ^^^^^
25
+ # This
26
+ def negative?
27
+ !positive?
28
+ end
29
+
30
+ # @return [true, false] True if this token is for OR filter
31
+ # @note `Ruby OR Perl`
32
+ # ^^
33
+ # This
34
+ def or?
35
+ @token_string.downcase == "or"
36
+ end
37
+
38
+ # @return [true, false] Opposite of #negative?
39
+ def positive?
40
+ @minus.nil?
41
+ end
42
+
43
+ # @return [true, false] True if this token is for phrase matching
44
+ # @note `Express OR "Ruby on Rails"`
45
+ # ^^^^^^^^^^^^^^^
46
+ # This
47
+ def quoted?
48
+ !!@quoted
49
+ end
50
+
51
+ def should?
52
+ !must? && !must_not?
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,51 @@
1
+ require "qiita/elasticsearch/token"
2
+
3
+ module Qiita
4
+ module Elasticsearch
5
+ class Tokenizer
6
+ DEFAULT_FILTERABLE_FIELDS = []
7
+
8
+ TOKEN_PATTERN = /
9
+ (?<token_string>
10
+ (?<minus>-)?
11
+ (?:(?<field_name>\w+):)?
12
+ (?:
13
+ (?:"(?<quoted_term>.*?)(?<!\\)")
14
+ |
15
+ (?<term>\S+)
16
+ )
17
+ )
18
+ /x
19
+
20
+ # @param [Array<String>, nil] filterable_fields
21
+ def initialize(filterable_fields: nil)
22
+ @filterable_fields = filterable_fields
23
+ end
24
+
25
+ # @param [String] query_string Raw query string
26
+ # @return [Array<Qiita::Elasticsearch::Token>]
27
+ def tokenize(query_string)
28
+ query_string.scan(TOKEN_PATTERN).map do |token_string, minus, field_name, quoted_term, term|
29
+ term ||= quoted_term
30
+ if !field_name.nil? && !filterable_fields.include?(field_name)
31
+ term = "#{field_name}:#{term}"
32
+ field_name = nil
33
+ end
34
+ Token.new(
35
+ field_name: field_name,
36
+ minus: minus,
37
+ quoted: !quoted_term.nil?,
38
+ term: term,
39
+ token_string: token_string,
40
+ )
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def filterable_fields
47
+ @filterable_fields || DEFAULT_FILTERABLE_FIELDS
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,5 @@
1
+ module Qiita
2
+ module Elasticsearch
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "qiita/elasticsearch/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "qiita-elasticsearch"
7
+ spec.version = Qiita::Elasticsearch::VERSION
8
+ spec.authors = ["Ryo Nakamura"]
9
+ spec.email = ["r7kamura@gmail.com"]
10
+ spec.summary = "Elasticsearch client helper for Qiita."
11
+ spec.homepage = "https://github.com/increments/qiita-elasticsearch"
12
+ spec.license = "MIT"
13
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
14
+ spec.bindir = "bin"
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.require_paths = ["lib"]
17
+ spec.add_development_dependency "bundler", ">= 1.7"
18
+ spec.add_development_dependency "codeclimate-test-reporter"
19
+ spec.add_development_dependency "rake", "~> 10.0"
20
+ spec.add_development_dependency "rspec", "3.2.0"
21
+ spec.add_development_dependency "rubocop", "0.29.1"
22
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qiita-elasticsearch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ryo Nakamura
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: codeclimate-test-reporter
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 3.2.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 3.2.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 0.29.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 0.29.1
83
+ description:
84
+ email:
85
+ - r7kamura@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".rubocop.yml"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - lib/qiita/elasticsearch.rb
99
+ - lib/qiita/elasticsearch/nodes/bool_query_node.rb
100
+ - lib/qiita/elasticsearch/nodes/filter_query_node.rb
101
+ - lib/qiita/elasticsearch/nodes/match_query_node.rb
102
+ - lib/qiita/elasticsearch/nodes/null_node.rb
103
+ - lib/qiita/elasticsearch/nodes/or_separatable_node.rb
104
+ - lib/qiita/elasticsearch/nodes/token_node.rb
105
+ - lib/qiita/elasticsearch/parser.rb
106
+ - lib/qiita/elasticsearch/query_builder.rb
107
+ - lib/qiita/elasticsearch/token.rb
108
+ - lib/qiita/elasticsearch/tokenizer.rb
109
+ - lib/qiita/elasticsearch/version.rb
110
+ - qiita-elasticsearch.gemspec
111
+ homepage: https://github.com/increments/qiita-elasticsearch
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.4.5
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Elasticsearch client helper for Qiita.
135
+ test_files: []
136
+ has_rdoc: