Чи можна ЗАМОВИТИ результати за допомогою запиту чи сканування в DynamoDB?


83

Чи можна ЗАМОВИТИ результати за допомогою API запитів або сканування в DynamoDB?

Мені потрібно знати, чи DynamoDB має щось на зразок [ORDER BY 'field'] із запитів SQL?

Дякую.

Відповіді:


42

Не явно, однак, замовлення, очевидно, потрібне для багатьох справжніх випадків використання, і його можна змоделювати за допомогою первинного ключа хешу та діапазону відповідно:

У цьому випадку первинний ключ складається з двох атрибутів. Перший атрибут - це атрибут хешу, а другий - атрибут діапазону. Amazon DynamoDB створює невпорядкований хеш-індекс на атрибуті хеш-первинного ключа та відсортований індекс діапазону на атрибуті первинного ключа діапазону . [курсив мій]

Потім ви можете використовувати цей індекс діапазону для необов’язкового запиту елементів через параметр RangeKeyCondition параметра API запиту та вказівки обходу індексу вперед або назад (тобто напрямок сортування) за допомогою параметра ScanIndexForward .

Оновлення: Ви можете впорядкувати за атрибутом із локальним вторинним індексом таким же чином.


18
Параметр ScanIndexForward, здається, застосовується лише до запиту , а не Сканування правильно? Як можна повернути впорядкований перелік сторінок усіх елементів у таблиці за допомогою запиту? Здається, сканування - це спосіб повернути "*", але, схоже, він не має параметра для упорядкування результатів.
справа 2000

Я не використовував цю функцію, лише читав про неї, але Query підтримує вказівку обмеження , щоб обмежити кількість отриманих результатів, і якщо є більше елементів, які відповідають вашому запиту при досягненні обмеження, ви отримаєте LastEvaluatedKey за допомогою якого можна зробити ще один запит і продовжувати отримувати результати.
fernio

1
Важлива проблема: повернені результати насправді не будуть відсортовані. Сортування вступає в дію лише в тому випадку, якщо ви застосуєте значення "Обмеження" або кількість елементів перевищує межу пошуку в 1 МБ. Наприклад, у вас може бути 5 записів із ключем розділу 'p1' та клавішами сортування: ['b', 'd', 'a', 'c', 'e']. Якщо ви виконаєте запит лише для 'p1', ви отримаєте ['b', 'd', 'a', 'c', 'e']. Але якщо ви вкажете обмеження 2, воно поверне ['b', 'a']
jameslol

29

Ви можете використовувати клавішу сортування та застосувати параметр ScanIndexForward у запиті для сортування у порядку зростання або зменшення. Тут я обмежую елементи, що повертаються до 1.

var params = {
    TableName: 'Events',
    KeyConditionExpression: 'Organizer = :organizer',
    Limit: 1,
    ScanIndexForward: false,    // true = ascending, false = descending
    ExpressionAttributeValues: {
        ':organizer': organizer
    }
};

docClient.query(params, function(err, data) {
    if (err) {
        console.log(JSON.stringify(err, null, 2));
    } else {
        console.log(JSON.stringify(data, null, 2));
    }
});

8
Проблема в тому, що ви хочете повернути всі предмети. По суті, це означає, що вам потрібно створити новий фіктивний стовпець, призначити в ньому однакове значення всім рядкам, створити GSI для цього стовпця та викликати запит замість сканування.
JHH

що робити, якщо я хочу повернутися на основі якогось неключового поля? як створене_ числове поле
Юсуф

Тоді вам може знадобитися отримати всі записи, а потім відфільтрувати записи за допомогою JavaScript або подібного. DynamoDB - це в основному магазин ключових цінностей з обмеженими функціональними можливостями. Але це дуже швидко, коли ви можете використовувати клавіші.
kometen

7

Використовуйте ScanIndexForward (true для зростання та false для спадання), а також можете обмежити результат, використовуючи значення setLimit значення виразу запиту.

Нижче наведено код, де використовується QueryPage для пошуку окремого запису.

public void fetchLatestEvents() {
    EventLogEntitySave entity = new EventLogEntitySave();
    entity.setId("1C6RR7JM0JS100037_contentManagementActionComplete");

    DynamoDBQueryExpression<EventLogEntitySave> queryExpression = new DynamoDBQueryExpression<EventLogEntitySave>().withHashKeyValues(entity);
    queryExpression.setScanIndexForward(false);
    queryExpression.withLimit(1);
    queryExpression.setLimit(1);

    List<EventLogEntitySave> result = dynamoDBMapper.queryPage(EventLogEntitySave.class, queryExpression).getResults();
    System.out.println("size of records = "+result.size() );
}

@DynamoDBTable(tableName = "PROD_EA_Test")
public class EventLogEntitySave {

        @DynamoDBHashKey
        private String id;
        private String reconciliationProcessId;
        private String vin;
        private String source;
}

public class DynamoDBConfig {
    @Bean
    public AmazonDynamoDB amazonDynamoDB() {

            String accesskey = "";
            String secretkey = "";
            //
            // creating dynamo client
            BasicAWSCredentials credentials = new BasicAWSCredentials(accesskey, secretkey);
            AmazonDynamoDB dynamo = new AmazonDynamoDBClient(credentials);
            dynamo.setRegion(Region.getRegion(Regions.US_WEST_2));
            return dynamo;
        }

    @Bean
    public DynamoDBMapper dynamoDBMapper() {
        return new DynamoDBMapper(amazonDynamoDB());
    }
}

Використовуйте ScanIndexForward (true для зростання та false для спадання)
ABHAY JOHRI

2

Іншим варіантом, який повинен вирішити проблему, є

  1. Визначте локальний вторинний індекс за допомогою "звичайного" хеш-ключа, який також буде хеш-ключем LSI
  2. Визначте поле, яке потрібно відсортувати, як «Ключ сортування» LSI
  3. Запитайте LSI та встановіть порядок за бажанням (див. Вище)

Це дозволить сортувати будь-яке значення вашої таблиці за необхідності. Це дуже ефективний спосіб знайти найвищі позиції у вашій таблиці без необхідності отримувати весь запит, а потім фільтрувати його потім.


Що вище? Якщо звичайний хеш не впорядкований для згенерованого ідентифікатора сортування, включно він, здається, не працює. Мені чогось не вистачає?
Саманта

1

Якщо ви використовуєте boto2 і у вас є ключ сортування в одному зі стовпців у вашій таблиці, ви можете сортувати те, що ви отримуєте, по порядку або в зворотному порядку, сказавши:

result = users.query_2(
    account_type__eq='standard_user',
    reverse=True)

Якщо ви використовуєте boto3 і у вас у стовпці є ключ сортування, за яким ви хочете відсортувати результат, ви можете сортувати отримані дані, сказавши:

result = users.query(
    KeyConditionExpression=Key('account_type').eq('standard_user'),
    ScanIndexForward=True)

Пам’ятайте, що у файлі boto3 значення ScanIndexForward є істинним, DynamoDB повертає результати в тому порядку, в якому вони зберігаються (за значенням ключа сортування). Це поведінка за замовчуванням. Якщо ScanIndexForward хибне, DynamoDB зчитує результати у зворотному порядку за значенням ключа сортування, а потім повертає результати клієнту.


0

Якщо таблиця вже існувала, додайте GSI (Глобальний вторинний індекс) до атрибута, який потрібно для таблиці, і використовуйте Query, а не Scan. Якщо ви збираєтеся створити таблицю, ви можете додати LSI (Local Secondary Index) до потрібного атрибута.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.