Как мне выполнить запрос только по части составного ключа в DynamoDB?

#amazon-dynamodb #dynamodb-queries

#amazon-dynamodb #dynamodb-запросы

Вопрос:

Допустим, у меня есть User s, пишущий обзоры Product s.

Пользователь и продукт являются отдельными объектами со своими собственными идентификаторами.

Review является ли объект с составным идентификатором, состоящим из userId и productId .

Я создал таблицу review в DynamoDB с обоими userId и productId как хэш-ключами.

 aws dynamodb create-table --table-name review 
  --attribute-definitions 
      AttributeName=user_id,AttributeType=S 
      AttributeName=product_id,AttributeType=S 
  --key-schema 
      AttributeName=user_id,KeyType=HASH 
      AttributeName=product_id,KeyType=RANGE 
  --provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=5 
  

Таким образом, создается userId productId составной ключ.

Объект данных проверки хранится по этому ключу.

Запрос на отзыв пользователя и продукта — это нормально.

Но как мне запросить все отзывы пользователя или все отзывы о продукте?

С одним параметром, например, если я выполняю запрос с помощью одного ключевого условного выражения с помощью just "#user_id = :userId" или just "#product_id = :productId"

Я получаю сообщение об ошибке вида

 Query condition missed key schema element: user_id
  

или

 Query condition missed key schema element: product_id
  

Комментарии:

1. Можете ли вы показать полный запрос, который выдает ошибку?

Ответ №1:

Я создал обзор таблицы в DynamoDB с идентификаторами пользователя и ProductID в качестве ХЭШ-ключей.

Вы создали составной первичный ключ для своей таблицы просмотра, который состоит из ключа раздела userId и a и ключа сортировки ‘ProductID’ . Вы не создали два ХЭШ-ключа.

По логике вещей, ваша обзорная таблица будет выглядеть примерно так (я привел некоторые данные для иллюстрации).:

обзорная таблица

Эта структура таблицы упрощает получение отзывов пользователем. Вот пример запроса для всех обзоров USER#ABC

 ddbClient.query(
  "TableName": "<YOUR TABLE NAME>",
  "KeyConditionExpression": "#userId = :userId",
  "ExpressionAttributeValues": {
    ":userId": {
      "S": "USER#ABC"
    }
  },
  "ExpressionAttributeNames": {
    "#userId": "userId"
  }
)

  

Это вернет коллекцию элементов, просмотренных ПОЛЬЗОВАТЕЛЕМ #ABC.

DynamoDB не позволит вам извлекать элементы, указав только ключ сортировки (например, ProductID). Вам всегда нужно указывать ключ раздела. Итак, как вы получаете список пользователей, которые рассмотрели данный продукт?

Если вы хотите выполнить поиск по всем пользователям, которые просмотрели один продукт, вы можете ввести глобальный вторичный индекс, который меняет местами ключ раздела и ключ сортировки вашей таблицы. Этот шаблон известен как инвертированный индекс. Используя мой пример выше, инвертированный индекс будет выглядеть следующим образом:

глобальный вторичный индекс по productid

Это позволит вам получать пользователей по идентификатору продукта:

 ddbclient.query(
{
  "TableName": "<YOUR TABLE NAME>",
  "IndexName": "reviews_by_product_index",
  "KeyConditionExpression": "#productId = :productId",
  "ExpressionAttributeValues": {
    ":productId": {
      "S": "PRODUCT#456"
    }
  },
  "ExpressionAttributeNames": {
    "#productId": "productId"
  }
}
)
  

Этот запрос вернет коллекцию из двух элементов, представляющих обзоры для PRODUCT#456 .

При работе с составным первичным ключом вы можете выполнять поиск на основе условий ключа сортировки, если вы также указываете ключ раздела. Это полный рот, но он позволяет выполнять запросы типа (в псевдокоде)

запрос, где ключ раздела = «USER #ABC», а ключ сортировки начинается с «PRODUCT»

Комментарии:

1. Потрясающий ответ. Спасибо.

2. у меня это не работает: ГДЕ business_id#type_id#partner_id=435634652 #3 #69992528