Запрос БД Dynamo не возвращает ожидаемых результатов при использовании вложенных коллекций - PullRequest
1 голос
/ 27 марта 2020

У меня есть AWS Таблица DynamoDB со следующей структурой:

dynamo table

Я пытаюсь вернуть все элементы, которые имеют по крайней мере один RequestItem с идентификатором 3401. Вот что я пробовал до сих пор (c# код):

     IAmazonDynamoDB client = new AmazonDynamoDBClient(
            new BasicAWSCredentials(configuration["AccessKey"], configuration["SecretKey"]),
            RegionEndpoint.USEast1);

        var request = new ScanRequest
        {
            TableName = "dynamo-table-name",
            ExpressionAttributeNames = new Dictionary<string, string>
            {
                {"#requestItems", "RequestItems"},
                {"#requestId", "Id"}
            },
            ExpressionAttributeValues = new Dictionary<string, AttributeValue>
            {
                {":val", new AttributeValue {N = "3401"}}
            },
            FilterExpression = "contains(#requestItems.#requestId, :val)"
        };
        var response = await client.ScanAsync(request);

Я сделал несколько изменений в FilterExpression (используя простое «=» вместо «Содержит» ) но ... я все еще не вернул результаты. Запрос проходит без ошибок, но в результате получается пустой список.

Однако тот же код работает для свойств, которые не являются коллекциями (например, Contact.EmailAddress)

Чего мне не хватает?

[РЕДАКТИРОВАТЬ]

Я попробовал другое предложенное решение:

 var request = new ScanRequest
        {
            TableName = "dynamo-table-name",
            ExpressionAttributeNames = new Dictionary<string, string>
            {
                {"#requestItems", "RequestItems"}
            },
            ExpressionAttributeValues = new Dictionary<string, AttributeValue>
            {
                {
                    ":val",
                    new AttributeValue
                    {
                        L = new List<AttributeValue>
                        {
                            {
                                new AttributeValue
                                {
                                    M = new Dictionary<string, AttributeValue>
                                        {{"Id", new AttributeValue {N = "3401"}}}
                                }
                            }
                        }
                    }
                }
            },
            FilterExpression = "contains(#requestItems, :val)"
        };
        var response = await client.ScanAsync(request);

, но я все еще не получаю результаты.

Ответы [ 2 ]

3 голосов
/ 06 апреля 2020

Вы не можете сделать запрос, который хотите, с DynamoDB. Единственное, что вы можете сделать, если вы знаете максимальное количество элементов, которое может быть в RequestItems, - это объединить множество contains чеков с OR: (RequestItems.0.Id = :val) OR (RequestItems.1.Id = :val) OR (RequestItems.2.Id = :val) .... Это не кажется хорошей идеей, если только вы заранее не знаете, что RequestItems всегда будет содержать определенное, небольшое количество элементов.

contains не работает так, как вы этого хотите. Если вы делаете contains(path, <some number>), DynamoDB проверяет, является ли значение, найденное в path, набором чисел и содержится ли значение, указанное в <some number>, в этом наборе.

I Боюсь, что ваша единственная возможность, учитывая вашу схему данных, - это извлечь все элементы и отфильтровать их в вашем коде.

1 голос
/ 06 апреля 2020

Я прошу прощения, если это не является официальным.

Я подозреваю, что DynamoDB не может этого сделать .

Более того, идея DynamoDB заключается в том, что он должен не сделать это.

DynamoDB не поддерживает оценку произвольных функций по данным.

DynamoDB - это KV (своего рода), хранилище, а не база данных. «Динамо» - это запрос всех строк (элементов), которые вам могут понадобиться, и анализ столбцов (ключей) на стороне клиента. Обратите внимание, что он стоит точно так же (для динамо-машин, небольшая разница для трафика c), потому что aws взимает плату за что-то вроде «чтения с диска базы данных». И что это так же громоздко или просто, например, вам все еще приходится иметь дело с нумерацией страниц.

...