使用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-打开” “ 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-”开头,并且那是真实的。
如果是这样,我只需使用值“ TR-0d798900-a852-4a75-bef0-5dd5c96c657c-Module1-2019-04-02T12:24:19.000Z-”再次使用BeginsWith进行查询
它应该返回所有三个项目。它返回0个项目。
我想我做错了,感谢一些帮助。