DynamoDB: запрос для поиска элемента в массиве строк

Возможно, я не совсем понимаю, как хэш / первичные ключи работают в DynamoDB, но я пытаюсь создать модель (используя Serverless + Dynogels/NodeJS) для службы сообщений.

Модель выглядит так:

const ConversationORM = dynogels.define('Conversation', {

  hashKey: 'id',

  timestamps: true,
  tableName: config.CONVERSATION_TABLE,

  schema: {

    id: Joi.string(),
    users: Joi.array(), // e.g. ['foo', 'bar', 'moo']
    messages: Joi.array()

  }
})

Как вы видете, users массив, в котором перечислены идентификаторы участников беседы

Мне нужно создать сервис, который находит все разговоры, в которых участвует пользователь. В MongoDB (с которой я гораздо лучше знаком) я бы сделал что-то вроде:

Conversation.find({users: {"$in": ['foo']} }).then(.... 

Есть ли что-то эквивалентное, что я могу сделать в DynamoDB? Это вызов API, который будет происходить довольно часто, поэтому я надеюсь сделать его максимально эффективным.

2 ответа

Этот ответ принимает во внимание комментарий к ответу Хантера Фрейзера о том, что вы не хотите использовать сканирование.

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

Если вам нужно сделать этот запрос, я бы предложил пересмотреть вашу схему. В частности, я бы предложил реализовать шаблон списка Смежности, который хорошо работает в базах данных, содержащих отношения "многие ко многим".

Вы можете видеть некоторые дополнительные примечания к статье выше, которую я написал для этого ответа. Шаблон проектирования списка смежности MM DynamoDB

В вашем случае вы бы имели:

  • Первичный ключ: ConversationID
  • Ключ сортировки: идентификатор пользователя
  • Первичный ключ GSI: идентификатор пользователя

Затем вы можете использовать первичный ключ GSI в запросе, чтобы вернуть все разговоры, частью которых является пользователь.

Я не знаком с Dynogels или Serverless, но если он использует обычный API, это может сработать:

var params = {
    ExpressionAttributeNames: {
        "U": "users"
    },
    ExpressionAttributeValues: {
        ":a": {
            S: "John Doe"
        }
    },
    FilterExpression: "Author = :a",
    ProjectionExpression: "#U",
    TableName: "Conversations"
};
dynamodb.scan(params, function (err, data) {
    if (err) console.log(err, err.stack);
    else console.log(data);
});
Другие вопросы по тегам