scalastic 0.1.0 → 0.2.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: 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