README.md in fmrest-0.7.1 vs README.md in fmrest-0.8.0
- old
+ new
@@ -193,11 +193,11 @@
# Passing options for Redis.new
FmRest.token_store = FmRest::TokenStore::Redis.new(prefix: "my-fancy-prefix:", host: "10.0.1.1", port: 6380, db: 15)
```
-**NOTE:** redis-rb is not included as a gem dependency of fmrest-ruby, so you'll
+NOTE: redis-rb is not included as a gem dependency of fmrest-ruby, so you'll
have to add it to your Gemfile.
### Moneta
[Moneta](https://github.com/moneta-rb/moneta) is a key/value store wrapper
@@ -230,11 +230,11 @@
file: "tmp/tokens.yml",
prefix: "my-tokens"
)
```
-**NOTE:** the moneta gem is not included as a dependency of fmrest-ruby, so
+NOTE: the moneta gem is not included as a dependency of fmrest-ruby, so
you'll have to add it to your Gemfile.
## Date fields
@@ -553,11 +553,11 @@
```ruby
Honeybee.limit(10)
```
NOTE: You can also set a default limit value for a model class, see
-[Other notes on querying](#other-notes-on-querying).
+[other notes on querying](#other-notes-on-querying).
You can also use `.limit` to set limits on portals:
```ruby
Honeybee.limit(hives: 3, flowers: 2)
@@ -725,29 +725,75 @@
```ruby
Honeybee.limit(10).sort(:name).find_some # => [<Honeybee...>, ...]
```
-If you want just a single result you can use `.find_one` instead (this will
+If you want just a single result you can use `.first` instead (this will
force `.limit(1)`):
```ruby
-Honeybee.query(name: "Hutch").find_one # => <Honeybee...>
+Honeybee.query(name: "Hutch").first # => <Honeybee...>
```
If you know the id of the record you should use `.find(id)` instead of
-`.query(id: id).find_one` (so that the sent request is
+`.query(id: id).first` (so that the sent request is
`GET ../:layout/records/:id` instead of `POST ../:layout/_find`).
```ruby
Honeybee.find(89) # => <Honeybee...>
```
Note also that if you use `.find(id)` your `.query()` parameters (as well as
limit, offset and sort parameters) will be discarded as they're not supported
by the single record endpoint.
+
+### Finding records in batches
+
+Sometimes you want to iterate over a very large number of records to do some
+processing, but requesting them all at once would result in one huge request to
+the Data API, and loading too many records in memory all at once.
+
+To mitigate this problem you can use `.find_in_batches` and `.find_each`. If
+you've used ActiveRecord you're probably familiar with how they operate:
+
+```ruby
+# Find records in batches of 100 each
+Honeybee.query(hive: "Queensville").find_in_batches(batch_size: 100) do |batch|
+ dispatch_bees(batch)
+end
+
+# Iterate over all records using batches
+Honeybee.query(hive: "Queensville").find_each(batch_size: 100) do |bee|
+ bee.dispatch
+end
+```
+
+`.find_in_batches` yields collections of records (batches), while `.find_each`
+yields individual records, but using batches behind the scenes.
+
+Both methods accept a block-less form in which case they return an
+`Enumerator`:
+
+```ruby
+batch_enum = Honeybee.find_in_batches
+
+batch = batch_enum.next # => Spyke::Collection
+
+batch_enum.each do |batch|
+ process_batch(batch)
+end
+
+record_enum = Honeybee.find_each
+
+record_enum.next # => Honeybee
+```
+
+NOTE: By its nature, batch processing is subject to race conditions if other
+processes are modifying the database.
+
+
### Container fields
You can define container fields on your model class with `container`:
```ruby
@@ -781,10 +827,11 @@
* `:filename` - The filename to use when uploading (defaults to
`filename_or_io.original_filename` if available)
* `:content_type` - The MIME content type to use (defaults to
`application/octet-stream`)
+
### Script execution
The Data API allows running scripts as part of many types of requests.
#### Model.execute_script
@@ -868,11 +915,11 @@
separately, under their matching key.
```ruby
bee.save(script: { presort: "My Presort Script", after: "My Script" })
-Honeybee.last_request_metadata[:script]
+Honeybee.last_request_metadata.script
# => { after: { result: "oh hi", error: "0" }, presort: { result: "lo", error: "0" } }
```
#### Executing scripts through query requests
@@ -882,10 +929,10 @@
`.script` takes the same options object specified [above](#script-options-object-format):
```ruby
# Find one Honeybee record executing a presort and after script
-Honeybee.script(presort: ["My Presort Script", "parameter"], after: "My Script").find_one
+Honeybee.script(presort: ["My Presort Script", "parameter"], after: "My Script").first
```
The model class' `.last_request_metadata` will be set in case you need to get the result.
In the case of retrieving multiple results (i.e. via `.find_some`) the