DynamoDB LIKE '%' (содержит) поиск по массиву объектов, используя ключ от объекта, NodeJS - PullRequest
0 голосов
/ 14 октября 2019

Я пытаюсь использовать поиск "LIKE" на DynamoDB, где у меня есть массив объектов с использованием nodejs.

Просматривая документацию и другие похожие посты, которые я видел, это можно сделать с помощью параметра CONTAINS.

Мой вопрос: могу ли я выполнить сканирование или запрос по всем моим элементам в DynamoDBгде значение в моем объекте LIKE "Test 2".

Вот моя таблица DynamoDB

enter image description here

Вот как это выглядиткак JSON:

{
  "items": [
    {
      "description": "Test 1 Description",
      "id": "86f550e3-3dee-4fea-84e9-30df174f27ea",
      "image": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/86f550e3-3dee-4fea-84e9-30df174f27ea.jpg",
      "live": 1,
      "status": "new",
      "title": "Test 1 Title"
    },
    {
      "description": "Test 2 Description",
      "id": "e17dbb45-63da-4567-941c-bb7e31476f6a",
      "image": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/e17dbb45-63da-4567-941c-bb7e31476f6a.jpg",
      "live": 1,
      "status": "new",
      "title": "Test 2 Title"
    },
    {
      "description": "Test 3 Description",
      "id": "14ad228f-0939-4ed4-aa7b-66ceef862301",
      "image": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/14ad228f-0939-4ed4-aa7b-66ceef862301.jpg",
      "live": 1,
      "status": "new",
      "title": "Test 3 Title"
    }
  ],
  "userId": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}

Я пытаюсь выполнить сканирование / запрос, который будет просматривать ВСЕХ пользователей (каждую строку), просматривать ВСЕ элементы и возвращать ВСЕ экземпляры, где description LIKE«Тест 2».

Я пробовал варианты сканирования, как показано ниже:

{
      "TableName": "my-table",
      "ConsistentRead": false,
      "ExpressionAttributeNames": {
        "#items": "items",
      },
      "FilterExpression": "contains (#items, :itemVal)",
      "ExpressionAttributeValues": {
        ":itemVal": 
        {
          "M": {
            "description": {
              "S": "Test 2 Description"
            },
            "id": {
              "S": "e17dbb45-63da-4567-941c-bb7e31476f6a"
            },
            "image": {
              "S": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/e17dbb45-63da-4567-941c-bb7e31476f6a.jpg"
            },
            "live": {
              "N": "1"
            },
            "status": {
              "S": "new"
            },
            "title": {
              "S": "Test 2 Title"
            }
          }
        }
      }
    }

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

{
      "TableName": "my-table",
      "ConsistentRead": false,
      "ExpressionAttributeNames": {
        "#items": "items.description",
      },
      "FilterExpression": "contains (#items, :itemVal)",
      "ExpressionAttributeValues": {
        ":itemVal": 
        {
          "S": "Test 2"
        }
      }
    }

В качестве альтернативы, было бы лучше создать отдельную таблицу, в которойвсе предметы добавленыd и они связаны через userId? У меня всегда было впечатление, что в каждом приложении должна быть одна таблица, но в этом случае я думаю, что если бы у меня были все данные об элементах на верхнем уровне, сканирование было бы намного безопаснее и быстрее.

1 Ответ

0 голосов
/ 17 октября 2019

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

Во-первых, я не хочу две таблицы, поскольку это кажется излишним, и я не хочу, чтобы затраты на aws были связаны с двумя таблицами.

Это привело меня к реструктуризации первичных ключей с префиксами, которые я могу искатьс помощью запроса селектора DynamodB "BEGINS_WITH".

Пользователи будут добавлены как U_ {USER_ID}, а элементы будут добавлены как I_ {USER_ID} _ {ITEM_ID}, поэтому у меня есть только одна таблица для управления изаплатить за, и это позволяет мне запустить BEGINS_WITH "U_", чтобы получить список пользователей, или "I_", чтобы получить список элементов.

Затем я сведу данные элемента в виде строк, чтобы я мог выполнить "содержит"поиск по любому из данных элемента. Это также позволяет мне выполнить поиск «содержит {USER_ID}» по первичным ключам для элементов, чтобы я мог получить список элементов для конкретного пользователя.

Надеюсь, это поможет любому, кто может столкнуться с тем жевыпуск.

...