Почему мой вторичный индекс DynamoDB работает только с частичной частью ключа сортировки - PullRequest
1 голос
/ 01 апреля 2019

Запрос таблицы во вторичном индексе с использованием оператора BeginsWith не всегда возвращает правильные записи. Что может быть причиной этого?

У меня есть пример кода и я пробовал его с локальной таблицей DynamoDB и с таблицей в AWS. Результаты одинаковы.

Определение вторичного индекса:

        var gsiKey1Index = new GlobalSecondaryIndex
        {
            IndexName = "GSIKey1Index",
            ProvisionedThroughput = new ProvisionedThroughput
            {
                ReadCapacityUnits = 1,
                WriteCapacityUnits = 1
            },
            Projection = new Projection { ProjectionType = "ALL" }
        };

        var indexKey1Schema = new List<KeySchemaElement> {
            {
                new KeySchemaElement
                {
                    AttributeName = "HashKey", KeyType = KeyType.HASH
                }
            },  //Partition key
            {
                new KeySchemaElement
                {
                    AttributeName = "GSISortKey1", KeyType = KeyType.RANGE
                }
            }  //Sort key
        };
        gsiKey1Index.KeySchema = indexKey1Schema;

Создание таблицы:

        var request = new CreateTableRequest
        {
            TableName = "TestTable",
            AttributeDefinitions = new List<AttributeDefinition>
            {
                new AttributeDefinition
                {
                    AttributeName = "HashKey",
                    // "S" = string, "N" = number, and so on.
                    AttributeType = "S"
                },
                new AttributeDefinition
                {
                    AttributeName = "SortKey",
                    AttributeType = "S"
                },
                new AttributeDefinition
                {
                AttributeName = "GSISortKey1",
                // "S" = string, "N" = number, and so on.
                AttributeType = "S"
            },

            },
            KeySchema = new List<KeySchemaElement>
            {
                new KeySchemaElement
                {
                    AttributeName = "HashKey",
                    // "HASH" = hash key, "RANGE" = range key.
                    KeyType = "HASH"
                },
                new KeySchemaElement
                {
                    AttributeName = "SortKey",
                    KeyType = "RANGE"
                },
            },
            GlobalSecondaryIndexes = { gsiKey1Index },
            ProvisionedThroughput = new ProvisionedThroughput
            {
                ReadCapacityUnits = 10,
                WriteCapacityUnits = 5
            },
        };


        response2 = await _client.CreateTableAsync(request);

Сущность выглядит так:

[DynamoDBTable("TestTable")]
public sealed class TestResult
{
    [DynamoDBHashKey]
    public string HashKey {get;set;}
    public string SortKey {get;set;}
    public string GSISortKey1 {get; set;}
}

Код для запроса выглядит так:

    public async Task<List<TestResult>> GetTestResultByDateTimeAsync(Guid hashid, Guid someId, string someName, DateTime timestamp)
    {
        var key2 = $"TR-{someId}-{someName}-{timestamp:yyyy-MM-ddTHH\\:mm\\:ss.fffZ}";
        var key = $"TR-{someId}-{someName}-{timestamp:yyyy-MM-dd}";
        //var filter = new QueryFilter();
        //filter.AddCondition("HashKey", ScanOperator.Equal, hashid.ToString());
        //filter.AddCondition("GSISortKey1", ScanOperator.BeginsWith, key);
        //var queryConfig = new QueryOperationConfig
        //{
        //    Filter = filter
        //};
        DynamoDBOperationConfig operationConfig = new DynamoDBOperationConfig()
        {
            OverrideTableName = "DEVTransponderTR",
            IndexName = "GSIKey1Index",
            QueryFilter = new List<ScanCondition>()
        };
        var sc = new ScanCondition("GSISortKey1", ScanOperator.BeginsWith, new[] { key });
        operationConfig.QueryFilter.Add(sc);
        var search = _context.QueryAsync<TestResult>(tenantid.ToString(), operationConfig);
        var testresults = await search.GetRemainingAsync();
        bool keywasok = true;
        foreach (var testresult in testresults)
        {
            keywasok = testresult.GSISortKey1.StartsWith(key2) && keywasok;
        }

        if (keywasok) // this means I should find the same values if I use key2
        {
            DynamoDBOperationConfig operationConfig2 = new DynamoDBOperationConfig()
            {
                OverrideTableName = "TestTable",
                IndexName = "GSIKey1Index",
                QueryFilter = new List<ScanCondition>()
            };
            var sc2 = new ScanCondition("GSISortKey1", ScanOperator.BeginsWith, new[] { key2 });
            operationConfig2.QueryFilter.Add(sc2);
            var search2 = _context.QueryAsync<TestResult>(tenantid.ToString(), operationConfig);
            var testresults2 = await search.GetRemainingAsync();


        }

        return testresults;
    }

Затем я добавляю три экземпляра в таблицу. важен тот факт, что вся информация одинакова за исключением значения GSISortKey1. Это значение GSISortKey1 для трех элементов:

"TR-0d798900-a852-4a75-bef0-5dd5c96c657c-Module1-2019-04-02T12: 24: 19.000Z-Open" "TR-0d798900-a852-4a75-bef0-5dd5c96c657c-Module1-2019-04-02T12: 24: 19.000Z-Отправить" "TR-0d798900-a852-4a75-bef0-5dd5c96c657c-Module1-2019-04-02T12: 24: 19.000Z-Test"

Итак, в примере я сначала запрашиваю «BeginsWith» со значением «TR-0d798900-a852-4a75-bef0-5dd5c96c657c-Module1-2019-04-02» (это ключ var)

Возвращает все три элемента.

Затем я проверяю, будет ли полное значение GSISortKey1 трех возвращаемых элементов также начинаться со значения "TR-0d798900-a852-4a75-bef0-5dd5c96c657c-Module1-2019-04-02T12: 24: 19.000Z-", и это правда.

Если это правда, я просто запрашиваю снова с BeginsWith, используя значение "TR-0d798900-a852-4a75-bef0-5dd5c96c657c-Module1-2019-04-02T12: 24: 19.000Z-"

Он должен вернуть все три предмета. возвращает 0 предметов.

Полагаю, я делаю что-то не так, нужна помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...