kitar / laravel-dynamodb

A DynamoDB based Eloquent model and Query builder for Laravel.
MIT License
179 stars 27 forks source link

Sorting does not work #20

Closed mohsinsiyal-tsi closed 2 years ago

mohsinsiyal-tsi commented 2 years ago

Hi, I am trying to sort the data with sort key but it's not working. Schema:

        $schema = [
            'AttributeDefinitions' => [
                [
                    'AttributeName' => 'id',
                    'AttributeType' => 'S',
                ],
                [
                    'AttributeName' => 'customer_id',
                    'AttributeType' => 'N',
                ],
                [
                    'AttributeName' => 'created_at',
                    'AttributeType' => 'S',
                ],
            ],
            'TableName' => $this->tableName,
            'KeySchema' => [
                [
                    'AttributeName' => 'id',
                    'KeyType' => 'HASH',
                ],
                [
                    'AttributeName' => 'created_at',
                    'KeyType' => 'RANGE',
                ],
            ],
            'StreamSpecification' => [
                'StreamEnabled' => true,
                'StreamViewType' => 'NEW_AND_OLD_IMAGES',
            ],
            'GlobalSecondaryIndexes' => [
                [
                    'IndexName' => 'gsi_0',
                    'Projection' => [
                        'ProjectionType' => 'ALL',
                    ],
                    'KeySchema' => [
                        [
                            'AttributeName' => 'customer_id',
                            'KeyType' => 'HASH',
                        ],
                        [
                            'AttributeName' => 'created_at',
                            'KeyType' => 'RANGE',
                        ],
                    ],
                    'BillingMode' => 'PAY_PER_REQUEST',
                ],
            ],
            'BillingMode' => 'PAY_PER_REQUEST',
        ];

Model:

class AuditLog extends Model
{
    protected $connection= 'dynamodb';
    protected $table = "";
    protected $primaryKey = 'id';
    protected $sortKey = 'created_at';
    protected $fillable = ["id", "log_text", "customer_id", "created_at"];
}

Controller:

$data = AuditLog::limit(5)->scanIndexForward(false)->scan();
$response = [
    "success" => true,
    "data" => $data, 
];
return response($response, 201);
kitar commented 2 years ago

@mohsinsiyal-tsi I think we cannot sort the results of scan before fetching all data. ScanIndexForward is a feature for query.

In addition, DynamoDB cannot sort items across multiple partitions. We need to put items in the same partition to sort them.

It seems you can use your gsi_0 to sort items for specific customer_id. For example:

$res = AuditLog::index('gsi_0')
               ->keyCondition('customer_id', '=', 1)
               ->scanIndexForward(false)
               ->query();
mohsinsiyal-tsi commented 2 years ago

Yes you are right.. What was I thinking. Sorting can only be done with query and not scan.