Запрос таблицы во вторичном индексе с использованием оператора 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 предметов.
Полагаю, я делаю что-то не так, нужна помощь.