Запрос параметра, который не является индексом в DynamoDb

TableName: люди

id | имя | возраст | место нахождения

id_1 | А | 23 | Новая Зеландия

id_2 | B | 12 | Индия

id_3 | C | 26 | Сингапур

id_4 | D | 30 | Турция

ключи: id -> хэш и возраст -> диапазон

Вопрос 1

Я пытаюсь выполнить запрос: «Выбрать * из людей, возраст которых> 25». Я могу заставить его работать с такими запросами, как «Выбрать возраст из людей, у которых id = id_1 и возраст> 25», что мне не нужно, просто нужно для выбора всех значений.

И если мне не нужно, чтобы возраст был индексом диапазона, как мне изменить параметры запроса, чтобы просто возвращать список записей, соответствующих критерию: возраст> 25?

Вопрос 2

AWS выдает ошибку, когда комментируются строки 23 или 24-41. : Ошибка запроса: ValidationException: в запросе должен быть указан параметр KeyConditions или KeyConditionExpression. код состояния: 400, идентификатор запроса: []

Требуется ли параметр KeyConditions / KeyConditionsExpressions? Означает ли это, что я не могу запросить таблицу по параметру, который не является частью индекса?

  func queryDynamo() {
        log.Println("Enter queryDynamo")

        svc := dynamodb.New(nil)

        params := &dynamodb.QueryInput{
            TableName: aws.String("people"), // Required
            Limit:     aws.Long(3),
            // IndexName: aws.String("localSecondaryIndex"),
            ExpressionAttributeValues: map[string]*dynamodb.AttributeValue{
                ":v_age": { // Required
                    N: aws.String("25"),
                },
                ":v_ID": {
                    S: aws.String("NULL"),
                },
            },
            FilterExpression: aws.String("age >= :v_age"),

            // KeyConditionExpression: aws.String("id = :v_ID and age >= :v_age"),
            KeyConditions: map[string]*dynamodb.Condition{
                "age": { // Required
                    ComparisonOperator: aws.String("GT"), // Required
                    AttributeValueList: []*dynamodb.AttributeValue{
                        { // Required
                            N: aws.String("25"),
                        },
                        // More values...
                    },
                },
                "id": { // Required
                    ComparisonOperator: aws.String("EQ"), // Required
                    // AttributeValueList: []*dynamodb.AttributeValue{
                    //  S: aws.String("NOT_NULL"),
                    // },
                },
                // More values...
            },
            Select:           aws.String("ALL_ATTRIBUTES"),
            ScanIndexForward: aws.Boolean(true),
        }

//Get the response and print it out.
        resp, err := svc.Query(params) 

        if err != nil {
            log.Println("Query Error: ", err.Error())
        }

        // Pretty-print the response data.
        log.Println(awsutil.StringValue(resp))
    }

person sr_149    schedule 24.07.2015    source источник


Ответы (1)


DynamoDB - это система на основе NoSQL, поэтому вы не сможете получить все записи на основе условия для неиндексированного поля, не выполнив сканирование таблицы.

Сканирование таблицы заставит DynamoDB просмотреть каждую отдельную запись в таблице, что для большой таблицы будет очень затратным по времени (это медленно) или по деньгам (выделенное чтение IOPS).

Использование фильтра - это правильный подход, который позволит завершить операцию, если вы переключитесь с запроса на сканирование. В запросе всегда должен быть указан хэш-ключ.

Небольшое предупреждение: если вы планируете использовать операцию сканирования для таблицы, состоящей из более чем нескольких (менее 100) элементов, отображаемых во внешнем интерфейсе, вы будете разочарованы результатами. Если это какое-то задание cron или задача создания отчетов серверной части, когда время отклика не имеет значения, это приемлемый подход, но будьте осторожны, чтобы не исчерпать все ваши IOPS и не повлиять на внешние приложения.

person JaredHatfield    schedule 24.07.2015
comment
Спасибо, Джаред Хэтфилд, это было прекрасно! Точно не знал, как использовать операцию сканирования. Выяснилось, что использование локальных вторичных индексов может помочь, но однажды созданные они не могут быть изменены, а количество локальных вторичных индексов ограничено. - person sr_149; 27.07.2015