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