scalastic 0.1.0 → 0.2.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: 8d4a081eb653e2378d6a39f4f77cd51f44b553b0
4
- data.tar.gz: c38641e0fe62a596f2d631a7edbfc6c4276785b7
3
+ metadata.gz: fd3dbca7672a601bba49bc18531c66f5d4427710
4
+ data.tar.gz: 3669c3673f0ded567a2acec6993028195a3b2c44
5
5
  SHA512:
6
- metadata.gz: a46a54dd509265a69b621b5596bd21c23b3d766f1d4c479faa28436e69b5650bb133dba236316860eb8ae48cca864fdf9b1f06b1d20f28bfb898162287cefb03
7
- data.tar.gz: 252794ac6ea2ccb301636a90953e8a31ed2a3186ea079ba1c4894ffbc4ea86ddf41075e89f3e37d49a527ef7f5c05992c40bd46e86f4cc9e694d06a5920b330d
6
+ metadata.gz: d5ea03aa00e7513b8c33359480d1d3e49edeaf62e5408362ed4d156666adc4573dbb89872fa3824c838570407768f65ddd0dba52cf723621d969e6ad6602aeb3
7
+ data.tar.gz: 46cfbf9227dc75f94e6e2ea0defa7979e8ddf55cd38f31817b047e043b979983badf578d10e098ed784f317186a8ea4162ee69e40f8a5b6743d7270a355d2b68
data/README.md CHANGED
@@ -135,6 +135,67 @@ count = partition1.search(search_type: 'count', body: {query: {match_all: {}}})[
135
135
  raise "Expected 1 document, got #{count}" unless count == 1
136
136
  ```
137
137
 
138
+ ### Bulk operations
139
+ ```ruby
140
+ client = Elasticsearch::Client.new
141
+ partitions = client.partitions
142
+
143
+ client.indices.create(index: 'bulk_operations')
144
+ partitions.prepare_index(index: 'bulk_operations')
145
+
146
+ partition = partitions.create(index: 'bulk_operations', id: 1)
147
+
148
+ partition.bulk(body: [
149
+ {index: {_type: 'test', _id: 1, data: {subject: 'test1'}}},
150
+ {create: {_type: 'test', _id: 2, data: {subject: 'test2'}}}
151
+ ])
152
+
153
+ partition.bulk(body: [
154
+ {index: {_type: 'test', _id: 3}},
155
+ {subject: 'test3'},
156
+ {create: {_type: 'test', _id: 4}},
157
+ {subject: 'test4'}
158
+ ])
159
+
160
+ partition.bulk(body: [
161
+ {update: {_type: 'test', _id: 1, data: {doc: {body: 'Document 1'}}}},
162
+ {update: {_type: 'test', _id: 2, data: {doc: {body: 'Document 2'}}}}
163
+ ])
164
+
165
+ partition.bulk(body: [
166
+ {update: {_type: 'test', _id: 3}},
167
+ {doc: {body: 'Document 3'}},
168
+ {update: {_type: 'test', _id: 4}},
169
+ {doc: {body: 'Document 4'}}
170
+ ])
171
+
172
+ client.indices.refresh # Commit all pending writes
173
+
174
+ hits = partition.search['hits']['hits'].sort{|h1, h2| h1['_id'].to_i <=> h2['_id'].to_i}
175
+ raise 'Unexpected count' unless hits.size == 4
176
+
177
+ expected_hits = [
178
+ {'_index' => 'bulk_operations', '_type' => 'test', '_id' => '1', '_score' => 1.0, '_source' => {'subject' => 'test1', 'body' => 'Document 1', 'scalastic_partition_id' => 1}},
179
+ {'_index' => 'bulk_operations', '_type' => 'test', '_id' => '2', '_score' => 1.0, '_source' => {'subject' => 'test2', 'body' => 'Document 2', 'scalastic_partition_id' => 1}},
180
+ {'_index' => 'bulk_operations', '_type' => 'test', '_id' => '3', '_score' => 1.0, '_source' => {'subject' => 'test3', 'body' => 'Document 3', 'scalastic_partition_id' => 1}},
181
+ {'_index' => 'bulk_operations', '_type' => 'test', '_id' => '4', '_score' => 1.0, '_source' => {'subject' => 'test4', 'body' => 'Document 4', 'scalastic_partition_id' => 1}},
182
+ ]
183
+
184
+ raise 'Unexpected results' unless hits == expected_hits
185
+
186
+ res = partition.bulk(body: [
187
+ {delete: {_type: 'test', _id: 1}},
188
+ {delete: {_type: 'test', _id: 2}},
189
+ {delete: {_type: 'test', _id: 3}},
190
+ {delete: {_type: 'test', _id: 4}},
191
+ ])
192
+
193
+ client.indices.refresh # Commit all pending writes
194
+
195
+ count = partition.search(search_type: 'count')['hits']['total']
196
+ raise 'Some documents were not removed' unless count == 0
197
+ ```
198
+
138
199
  ### Notes
139
200
  * 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
201
  * All hash keys in arguments must be symbols; using anything else may result in unexpected behavior.
@@ -9,7 +9,7 @@ module Scalastic
9
9
 
10
10
  def initialize
11
11
  @partition_prefix = "scalastic"
12
- @partition_selector = "scalastic_partition_id"
12
+ @partition_selector = :scalastic_partition_id
13
13
  end
14
14
 
15
15
  def index_endpoint(partition_id)
@@ -51,10 +51,52 @@ module Scalastic
51
51
  all_aliases.any?{|_index, data| data['aliases'].any?}
52
52
  end
53
53
 
54
- #TODO: add bulk
54
+ def bulk(args)
55
+ body = args.clone[:body] || raise(ArgumentError, 'Missing required argument :body')
56
+ index = config.index_endpoint(id)
57
+ selector = config.partition_selector
58
+
59
+ new_ops = body.map{|entry| [operation_name(entry), entry]}.reduce([]){|acc, op| acc << [op.first, update_entry(acc, *op)]; acc}
60
+ args[:body] = new_ops.map{|_op, entry| entry}
61
+
62
+ es_client.bulk(args)
63
+ end
55
64
 
56
65
  def inspect
57
66
  "ES partition #{id}"
58
67
  end
68
+
69
+ private
70
+
71
+ def operation_name(entry)
72
+ [:create, :index, :update, :delete].find{|name| entry.has_key?(name)}
73
+ end
74
+
75
+ def update_entry(acc, operation, entry)
76
+ if (operation)
77
+ op_data = entry[operation]
78
+ op_data[:_index] = config.index_endpoint(id)
79
+ if (op_data[:data])
80
+ if (operation == :update)
81
+ op_data[:data][:doc] ||= {}
82
+ op_data[:data][:doc][config.partition_selector] = id
83
+ else
84
+ op_data[:data][config.partition_selector] = id
85
+ end
86
+ end
87
+ else
88
+ parent = acc.last
89
+ # A previous record must be create/index/update/delete
90
+ raise(ArgumentError, "Unexpected entry: #{entry}") unless parent && parent.first
91
+
92
+ if (parent.first == :update)
93
+ entry[:doc] ||= {}
94
+ entry[:doc][config.partition_selector] = id
95
+ else
96
+ entry[config.partition_selector] = id
97
+ end
98
+ end
99
+ entry
100
+ end
59
101
  end
60
102
  end
@@ -1,3 +1,3 @@
1
1
  module Scalastic
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scalastic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aliaksei Baturytski
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-01-12 00:00:00.000000000 Z
11
+ date: 2016-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler