scalastic 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +156 -0
- data/Rakefile +5 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/elasticsearch/transport_client.rb +9 -0
- data/lib/scalastic.rb +9 -0
- data/lib/scalastic/config.rb +37 -0
- data/lib/scalastic/es_actions_generator.rb +23 -0
- data/lib/scalastic/partition.rb +60 -0
- data/lib/scalastic/partitions_client.rb +53 -0
- data/lib/scalastic/version.rb +3 -0
- data/scalastic.gemspec +29 -0
- metadata +144 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8d4a081eb653e2378d6a39f4f77cd51f44b553b0
|
4
|
+
data.tar.gz: c38641e0fe62a596f2d631a7edbfc6c4276785b7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a46a54dd509265a69b621b5596bd21c23b3d766f1d4c479faa28436e69b5650bb133dba236316860eb8ae48cca864fdf9b1f06b1d20f28bfb898162287cefb03
|
7
|
+
data.tar.gz: 252794ac6ea2ccb301636a90953e8a31ed2a3186ea079ba1c4894ffbc4ea86ddf41075e89f3e37d49a527ef7f5c05992c40bd46e86f4cc9e694d06a5920b330d
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Alex Baturytski
|
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,156 @@
|
|
1
|
+
# Scalastic
|
2
|
+
|
3
|
+
Scalastic is a library that organizes your Elasticsearch documents into partitions, as recommended [here](https://www.elastic.co/guide/en/elasticsearch/guide/current/faking-it.html). A partition provides methods for indexing documents (adding or updating), searching for them, and deleting them. Partitions are isolated: documents stored in one partition are not visible in other partitions.
|
4
|
+
|
5
|
+
Initially your partition lives in a single index; however, as it grows, you may extend it to another index, redirecting all new documents there and keeping all documents from the original index available for searches. Partitions use Elasticsearch's filtered aliases; a partition with id 1 will create alias "scalastic_1_index" for indexing, and "scalastic_1_search" for searching. The index alias always points to a single index; the search one may span across multiple indices, with the most recent ones at the top.
|
6
|
+
|
7
|
+
Scalastic relies on the field "scalastic_partition_id" of type "long" to determine partition the document belongs to. The search alias for a partition has a term filter that returns only document belonging to that partition. The index alias, however, does not have a filter; if you're inserting documents into that alias directly (and not using Scalastic API), it becomes your responsibility to set this field to the correct value (which is partition id) for your document to show up in the partition. Note that delete API uses search alias to locate and delete documents to allow deletion of documents created in older indices.
|
8
|
+
|
9
|
+
## Configuring the environment for Scalastic
|
10
|
+
Every new index must be prepared before it can be used with scalastic:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
es_client = Elasticsearch::Client.new
|
14
|
+
es_client.indices.create index: 'my_index'
|
15
|
+
es_client.partitions.prepare index: 'my_index'
|
16
|
+
```
|
17
|
+
|
18
|
+
Preparing an index creates mappings for fields required by Scalastic. Note that preparing uses the _default_ mapping, which means that already existing document types will not be affected. Because of that **you should always prepare new indices before using them**.
|
19
|
+
|
20
|
+
## Installation
|
21
|
+
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
gem 'scalastic'
|
26
|
+
```
|
27
|
+
|
28
|
+
And then execute:
|
29
|
+
|
30
|
+
$ bundle
|
31
|
+
|
32
|
+
Or install it yourself as:
|
33
|
+
|
34
|
+
$ gem install scalastic
|
35
|
+
|
36
|
+
## Usage
|
37
|
+
|
38
|
+
Scalastic extends functionality of the Elasticsearch client by adding a property called "partitions" to the Elasticsearch client. That property serves as a gateway to all partitions' functionality.
|
39
|
+
|
40
|
+
### Creating a partition
|
41
|
+
```ruby
|
42
|
+
# Connect to Elasticsearch and get the partitions client
|
43
|
+
es_client = Elasticsearch::Client.new
|
44
|
+
partitions = es_client.partitions
|
45
|
+
|
46
|
+
# Create an index for the test.
|
47
|
+
es_client.indices.create index: 'create_partition_test'
|
48
|
+
partitions.prepare_index index: 'create_partition_test' # Must be called once per each index
|
49
|
+
|
50
|
+
# Create a partition
|
51
|
+
partition = partitions.create index: 'create_partition_test', id: 1
|
52
|
+
raise 'Partition was not created' unless partition.exists?
|
53
|
+
```
|
54
|
+
|
55
|
+
### Listing all existing partitions
|
56
|
+
```ruby
|
57
|
+
# Set everything up
|
58
|
+
client = Elasticsearch::Client.new
|
59
|
+
client.indices.create index: 'list_partitions_test'
|
60
|
+
partitions = client.partitions
|
61
|
+
partitions.prepare_index index: 'list_partitions_test' # Must be called once per each index
|
62
|
+
|
63
|
+
# Create a couple of partitions
|
64
|
+
partitions.create index: 'list_partitions_test', id: 1
|
65
|
+
partitions.create index: 'list_partitions_test', id: 2
|
66
|
+
partitions.create index: 'list_partitions_test', id: 3
|
67
|
+
|
68
|
+
# List all partitions
|
69
|
+
partitions.to_a.each{|p| puts "Found partition #{p.id}"}
|
70
|
+
```
|
71
|
+
|
72
|
+
### Deleting a partition
|
73
|
+
```ruby
|
74
|
+
# Connect to Elasticsearch and create an index
|
75
|
+
client = Elasticsearch::Client.new
|
76
|
+
partitions = client.partitions
|
77
|
+
client.indices.create index: 'delete_partition_test'
|
78
|
+
partitions.prepare_index index: 'delete_partition_test'
|
79
|
+
|
80
|
+
# Create partitions
|
81
|
+
partitions.create index: 'delete_partition_test', id: 1
|
82
|
+
partitions.create index: 'delete_partition_test', id: 2
|
83
|
+
partitions.create index: 'delete_partition_test', id: 3
|
84
|
+
|
85
|
+
# Delete one of the partitions
|
86
|
+
partitions.delete id: 2
|
87
|
+
raise "Partition still exists" if partitions[2].exists?
|
88
|
+
```
|
89
|
+
|
90
|
+
### Extending partition to another index
|
91
|
+
```ruby
|
92
|
+
# Connect to Elasticsearch and set up indices
|
93
|
+
client = Elasticsearch::Client.new
|
94
|
+
partitions = client.partitions
|
95
|
+
client.indices.create index: 'extend_partition_1'
|
96
|
+
partitions.prepare_index index: 'extend_partition_1'
|
97
|
+
client.indices.create index: 'extend_partition_2'
|
98
|
+
partitions.prepare_index index: 'extend_partition_2'
|
99
|
+
|
100
|
+
# Create a partition residing in extend_partition_1
|
101
|
+
partition = partitions.create(index: 'extend_partition_1', id: 1)
|
102
|
+
|
103
|
+
# Extend partition to index extend_partition_2. Now search will be performed in both indices, but
|
104
|
+
# all new documents will be indexex into extend_partition_2.
|
105
|
+
partition.extend_to(index: 'extend_partition_2')
|
106
|
+
```
|
107
|
+
|
108
|
+
### Operating documents inside partitions
|
109
|
+
```ruby
|
110
|
+
client = Elasticsearch::Client.new
|
111
|
+
partitions = client.partitions
|
112
|
+
|
113
|
+
client.indices.create index: 'partition_index'
|
114
|
+
partitions.prepare_index index: 'partition_index'
|
115
|
+
partition1 = partitions.create(index: 'partition_index', id: 1)
|
116
|
+
partition2 = partitions.create(index: 'partition_index', id: 2)
|
117
|
+
|
118
|
+
partition1.index id: 1, type: 'document', body: {subject: 'Subject 1'}
|
119
|
+
partition1.index id: 2, type: 'document', body: {subject: 'Subject 2'}
|
120
|
+
|
121
|
+
# Partition 2 should have no documents
|
122
|
+
count = partition2.search(search_type: 'count', body: {query: {match_all: {}}})['hits']['total']
|
123
|
+
raise 'Partition 2 is not empty!' unless count == 0
|
124
|
+
|
125
|
+
# Partiton 1 should contain everything we just indexed
|
126
|
+
hits = partition1.search(type: 'document', body: {query:{match_all: {}}})['hits']['hits']
|
127
|
+
raise "Expected 2 documents, got #{hits.size}" unless hits.size == 2
|
128
|
+
h1 = hits.find{|h| h['_id'].to_i == 1}
|
129
|
+
raise 'Document 1 cannot be found' unless h1
|
130
|
+
raise 'Invalid scalastic_partition_id' unless h1['_source']['scalastic_partition_id'] == 1
|
131
|
+
|
132
|
+
# Now delete something from partition 1
|
133
|
+
partition1.delete type: 'document', id: 1
|
134
|
+
count = partition1.search(search_type: 'count', body: {query: {match_all: {}}})['hits']['total']
|
135
|
+
raise "Expected 1 document, got #{count}" unless count == 1
|
136
|
+
```
|
137
|
+
|
138
|
+
### Notes
|
139
|
+
* Indices must be *prepared* before they can be used by Scalastic by calling "prepare" on the partitions client; doing so will create critical field mappings. Each index must be prepared only once.
|
140
|
+
* All hash keys in arguments must be symbols; using anything else may result in unexpected behavior.
|
141
|
+
|
142
|
+
|
143
|
+
## Development
|
144
|
+
|
145
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
146
|
+
|
147
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
148
|
+
|
149
|
+
## Contributing
|
150
|
+
|
151
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/aliakb/scalastic.
|
152
|
+
|
153
|
+
|
154
|
+
## License
|
155
|
+
|
156
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "scalastic"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/scalastic.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Scalastic
|
2
|
+
class Config
|
3
|
+
attr_reader(:partition_prefix)
|
4
|
+
attr_reader(:partition_selector)
|
5
|
+
|
6
|
+
def self.default
|
7
|
+
@default ||= new
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@partition_prefix = "scalastic"
|
12
|
+
@partition_selector = "scalastic_partition_id"
|
13
|
+
end
|
14
|
+
|
15
|
+
def index_endpoint(partition_id)
|
16
|
+
"#{partition_prefix}_#{partition_id}_index"
|
17
|
+
end
|
18
|
+
|
19
|
+
def search_endpoint(partition_id)
|
20
|
+
"#{partition_prefix}_#{partition_id}_search"
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_partition_id(alias_name)
|
24
|
+
m = partition_regex.match(alias_name)
|
25
|
+
m && m[1].to_i
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def partition_regex
|
31
|
+
@partition_regex ||= begin
|
32
|
+
escaped_prefix = Regexp.escape(partition_prefix)
|
33
|
+
Regexp.new("^#{escaped_prefix}_(\\w+)_(index|search)$")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Scalastic
|
2
|
+
module EsActionsGenerator
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def new_search_alias(config, args)
|
6
|
+
index = args[:index] || raise(ArgumentError, "Missing required argument :index")
|
7
|
+
id = args[:id] || raise(ArgumentError, "Missing required argument :id")
|
8
|
+
routing = args[:routing]
|
9
|
+
{index: index, alias: config.search_endpoint(id), filter: {term: {config.partition_selector => id}}}.tap do |op|
|
10
|
+
op.merge!(routing: routing) if routing
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def new_index_alias(config, args)
|
15
|
+
index = args[:index] || raise(ArgumentError, "Missing required argument :index")
|
16
|
+
id = args[:id] || raise(ArgumentError, "Missing required argument :id")
|
17
|
+
routing = args[:routing]
|
18
|
+
{index: index, alias: config.index_endpoint(id)}.tap do |op|
|
19
|
+
op.merge!(routing: routing) if routing
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'scalastic/es_actions_generator'
|
2
|
+
|
3
|
+
module Scalastic
|
4
|
+
class Partition
|
5
|
+
attr_reader(:es_client)
|
6
|
+
attr_reader(:config)
|
7
|
+
attr_reader(:id)
|
8
|
+
|
9
|
+
def initialize(es_client, config, id)
|
10
|
+
raise(ArgumentError, 'ES client is nil!') if es_client.nil?
|
11
|
+
raise(ArgumentError, 'config is nil!') if config.nil?
|
12
|
+
raise(ArgumentError, 'id is empty!') if id.nil? || id.to_s.empty?
|
13
|
+
|
14
|
+
@es_client = es_client
|
15
|
+
@config = config
|
16
|
+
@id = id
|
17
|
+
end
|
18
|
+
|
19
|
+
def extend_to(args)
|
20
|
+
index = args[:index]
|
21
|
+
raise(ArgumentError, 'Missing required argument :index') if index.nil? || index.to_s.empty?
|
22
|
+
|
23
|
+
index_alias = config.index_endpoint(id)
|
24
|
+
indices = es_client.indices.get_aliases(name: index_alias).select{|i, d| d['aliases'].any?}.keys
|
25
|
+
actions = indices.map{|i| {remove: {index: i, alias: index_alias}}}
|
26
|
+
actions << {add: EsActionsGenerator.new_index_alias(config, args.merge(id: id))}
|
27
|
+
actions << {add: EsActionsGenerator.new_search_alias(config, args.merge(id: id))}
|
28
|
+
es_client.indices.update_aliases(body: {actions: actions})
|
29
|
+
end
|
30
|
+
|
31
|
+
def search(args = {})
|
32
|
+
args = args.merge(index: config.search_endpoint(id))
|
33
|
+
es_client.search(args)
|
34
|
+
end
|
35
|
+
|
36
|
+
def index(args)
|
37
|
+
args = {body: {}}.merge(args)
|
38
|
+
args[:body][config.partition_selector.to_sym] = id
|
39
|
+
args = args.merge(index: config.index_endpoint(id))
|
40
|
+
es_client.index(args)
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(args = {})
|
44
|
+
args = args.merge(index: config.search_endpoint(id))
|
45
|
+
es_client.delete(args)
|
46
|
+
end
|
47
|
+
|
48
|
+
def exists?
|
49
|
+
names = [config.search_endpoint(id), config.index_endpoint(id)]
|
50
|
+
all_aliases = es_client.indices.get_aliases name: names.join(',')
|
51
|
+
all_aliases.any?{|_index, data| data['aliases'].any?}
|
52
|
+
end
|
53
|
+
|
54
|
+
#TODO: add bulk
|
55
|
+
|
56
|
+
def inspect
|
57
|
+
"ES partition #{id}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require "scalastic/partition"
|
2
|
+
require "scalastic/es_actions_generator"
|
3
|
+
|
4
|
+
module Scalastic
|
5
|
+
class PartitionsClient
|
6
|
+
attr_reader(:es_client)
|
7
|
+
attr_reader(:config)
|
8
|
+
|
9
|
+
def initialize(es_client, config = Config.default)
|
10
|
+
raise(ArgumentError, "ES client is nil") if es_client.nil?
|
11
|
+
raise(ArgumentError, "Config is nil") if config.nil?
|
12
|
+
@es_client = es_client
|
13
|
+
@config = config
|
14
|
+
end
|
15
|
+
|
16
|
+
def create(args = {})
|
17
|
+
actions = [
|
18
|
+
{add: EsActionsGenerator.new_search_alias(config, args)},
|
19
|
+
{add: EsActionsGenerator.new_index_alias(config, args)},
|
20
|
+
]
|
21
|
+
es_client.indices.update_aliases(body: {actions: actions})
|
22
|
+
self[args[:id]]
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete(args = {})
|
26
|
+
id = args[:id] || raise(ArgumentError, "Missing required argument :id")
|
27
|
+
pairs = es_client.indices.get_aliases.map{|i, d| d["aliases"].keys.select{|a| config.get_partition_id(a) == id}.map{|a| [i, a]}}.flatten(1)
|
28
|
+
unless pairs.any?
|
29
|
+
#TODO: log a warning
|
30
|
+
return
|
31
|
+
end
|
32
|
+
actions = pairs.map{|i, a| {remove: {index: i, alias: a}}}
|
33
|
+
es_client.indices.update_aliases(body: {actions: actions})
|
34
|
+
end
|
35
|
+
|
36
|
+
def [](id)
|
37
|
+
Partition.new(es_client, config, id)
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_a
|
41
|
+
aliases = es_client.indices.get_aliases
|
42
|
+
partition_ids = aliases.map{|_, data| data["aliases"].keys}.flatten.map{|a| config.get_partition_id(a)}.compact.uniq
|
43
|
+
partition_ids.map{|id| Partition.new(es_client, config, id)}
|
44
|
+
end
|
45
|
+
|
46
|
+
def prepare_index(args)
|
47
|
+
index = args[:index] || raise(ArgumentError, "Missing required argument :index")
|
48
|
+
mapping = {properties: {config.partition_selector => {type: "long"}}}
|
49
|
+
es_client.indices.put_mapping(index: index, type: "_default_", body: {"_default_" => mapping})
|
50
|
+
es_client.indices.put_mapping(index: index, type: "scalastic", body: {"scalastic" => mapping})
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/scalastic.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'scalastic/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "scalastic"
|
8
|
+
spec.version = Scalastic::VERSION
|
9
|
+
spec.authors = ["Aliaksei Baturytski"]
|
10
|
+
spec.email = ["abaturytski@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "Elasticsearch document partitions"
|
13
|
+
spec.description = "Elasticsearch alias-based partitions for scalable indexing and searching"
|
14
|
+
spec.homepage = "https://github.com/aliakb/scalastic"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.4"
|
25
|
+
spec.add_development_dependency "simplecov", "~> 0.11"
|
26
|
+
|
27
|
+
spec.add_dependency "elasticsearch", "~> 1.0"
|
28
|
+
spec.add_dependency "multi_json", "~> 1.0"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: scalastic
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aliaksei Baturytski
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-12 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.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.4'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.4'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.11'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.11'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: elasticsearch
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: multi_json
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.0'
|
97
|
+
description: Elasticsearch alias-based partitions for scalable indexing and searching
|
98
|
+
email:
|
99
|
+
- abaturytski@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".travis.yml"
|
106
|
+
- Gemfile
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- bin/console
|
111
|
+
- bin/setup
|
112
|
+
- lib/elasticsearch/transport_client.rb
|
113
|
+
- lib/scalastic.rb
|
114
|
+
- lib/scalastic/config.rb
|
115
|
+
- lib/scalastic/es_actions_generator.rb
|
116
|
+
- lib/scalastic/partition.rb
|
117
|
+
- lib/scalastic/partitions_client.rb
|
118
|
+
- lib/scalastic/version.rb
|
119
|
+
- scalastic.gemspec
|
120
|
+
homepage: https://github.com/aliakb/scalastic
|
121
|
+
licenses:
|
122
|
+
- MIT
|
123
|
+
metadata: {}
|
124
|
+
post_install_message:
|
125
|
+
rdoc_options: []
|
126
|
+
require_paths:
|
127
|
+
- lib
|
128
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
requirements: []
|
139
|
+
rubyforge_project:
|
140
|
+
rubygems_version: 2.4.5
|
141
|
+
signing_key:
|
142
|
+
specification_version: 4
|
143
|
+
summary: Elasticsearch document partitions
|
144
|
+
test_files: []
|