Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any idea for pagination? #37

Closed
phamquick opened this issue Nov 24, 2016 · 9 comments
Closed

Is there any idea for pagination? #37

phamquick opened this issue Nov 24, 2016 · 9 comments

Comments

@phamquick
Copy link

Is there any idea for pagination?

@baopham
Copy link
Owner

baopham commented Nov 24, 2016

Pagination isn't supported right now. But try chunk - it's the closest thing to pagination depending on your needs?

@baopham baopham closed this as completed Nov 24, 2016
@baopham
Copy link
Owner

baopham commented Nov 24, 2016

Oops, closing to soon. I will mark this as a feature request.

Pagination isn't supported but I would love to have it implemented. PR is welcome of course.

Related issue: #15

@asantibanez
Copy link

Pagination is supported in DynamoDB in the form of LastEvaluatedKey in the result set and ExclusiveStartKey when making a query or scan. See http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#Pagination

@baopham
Copy link
Owner

baopham commented Dec 2, 2016

Yep. We just need to get it in here :)

@zoul0813
Copy link
Contributor

A step forward for pagination?

https://github.com/baopham/laravel-dynamodb/compare/master...zoul0813:feature/skip-offset?expand=1

I added support for skip/offset and introduced setLastEvaluatedKey to the QueryBuilder. I also refactored the getCompositeKey method and added getCompositeKeyName to match the Eloquent getKey and getKeyName methods.

This doesn't introduce pagination, but allows you to use the primaryKey/compositeKey of a model to "skip".

For example, when calling chunk to walk through large datasets ... in the event of an error (ie; provisioned capacity issues) you can use the primaryKey/compositeKey of the last model evaluated as the lastEvaluatedKey and call chunk again, skipping anything you've already gone through.

I'm using this in a custom artisan command to reindex my DynamoDB Items in ElasticSearch. I occasionally run into provisioned capacity errors, and introducing this skip/offset modification has allowed me to "resume" after an error without having to go through all the items I've already processed.

Example of my "elasticsearch:reindex" command, taking advantage of "skip". I output the current models primaryKey/compositeKey values to the console so I can copy/paste them and pass them to the "--skip" parameter of the command to "resume".

<?php
namespace App\Console\Commands;

use Illuminate\Support\Facades\App;
use Illuminate\Console\Command;

use Exception;

class ElasticSearchReindex extends Command
{
  protected $signature = 'elasticsearch:reindex {model} {--size=100} {--rebuild} {--skip=*}';
  protected $description = 'DynamoDB Table Clear';

  public function handle()
  {
    $model = 'App\\' . $this->argument('model');
    $pageSize = (int)$this->option('size');
    $skip = $this->option('skip', null);

    $rebuild = filter_var($this->option('rebuild', false), FILTER_VALIDATE_BOOLEAN);

    if(!class_exists($model)) {
      $this->error('Invalid Class: ' . $model);
      die();
    }

    if($rebuild) {
      try {
        $this->warn('Deleting and rebuilding index');
        $model::deleteIndex();
        $model::createIndex();
        $model::putMapping();
        $this->info("Index Rebuilt (delete, create, put)");
      } catch(Exception $e) {
        $this->error($e->getMessage());
        die();
      }
    }

    // if $skip is empty, then lastEvaluatedKey is set to null
    $query = $model::skip($skip);

    $this->warn('pageSize: ' . $pageSize . ', skipping: ' . print_r($skip, true) . ', lastEvaluatedKey: ' . print_r($query->getLastEvaluatedKey(), true));

    try {
      $query->chunk($pageSize, function($models) {
        static $total = 0;
        $this->info('Total: ' . $total . ', Found: ' . count($models));
        foreach($models as $item) {
          try {
            $item->addToIndex();
            $this->line('Indexed: ' . $item->getKey() . ', ' . json_encode($item->getCompositeKey()) . ', ' . json_encode($item->getCompositeKeyValue()));
          } catch(Exception $e) {
            $this->error("EXCEPTION: " . $item->getKey() . ', ' . $e->getMessage() . ")");
          }
        }
        $total += count($models);
      });
    } catch(Exception $e) {
      $this->error("EXCEPTION: " . $e->getMessage());
    }
  }
}

@baopham I can create a PR if you'd like ...

@baopham
Copy link
Owner

baopham commented Oct 24, 2017

yep please go ahead.

@Saracevas
Copy link

Any progress on this?

@baopham
Copy link
Owner

baopham commented Nov 22, 2017

No, no update yet. During the holidays, I should have more time to look into it.

@baopham
Copy link
Owner

baopham commented Nov 25, 2017

@Saracevas pagination is now added. You can try v4.0.0. Please check README, since it's DynamoDB so we cannot match exactly with the same concept as relational DB.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants