使用全局二级索引从 dynamo 数据库 table 获取多条记录
Get multiple records from a dynamo db table using Global Secondary Index
我有一个发电机数据库 table CustomerOrders
具有以下字段
- 主分区键:CustomerId(数字)
- 主排序键:DepartmentId(数字)
- 订单(序列化 Json 字符串)
我想在不使用排序键 (DepartmentId) 的情况下在一个请求中查询多个客户。因此,我在 CustomerId 上创建了一个全局二级索引,并想用它来仅使用 CustomerId 进行查询。我看到的文档仅与 运行 批量查询的 BatchGetItemAsync
有关。我看不到在 BatchGetItemRequest 上设置 IndexName 的方法。怎么办?
下面是我目前的代码段:
public async Task<List<CustomerOrder>> GetOrdersAsync(List<int> customerIds)
{
var orders = new List<CustomerOrder>();
var tableKeys = new List<Dictionary<string, AttributeValue>>();
foreach (var x in customerIds)
{
tableKeys.Add(new Dictionary<string, AttributeValue> { { "CustomerId", new AttributeValue { N = x.ToString() } } });
}
var dynamoTable = $"CustomerOrders";
var keysAndAttributes = new KeysAndAttributes
{
AttributesToGet = new List<string> { "CustomerId", "DepartmentId", "Order" },
Keys = tableKeys
};
var request = new BatchGetItemRequest
{
ReturnConsumedCapacity = ReturnConsumedCapacity.INDEXES, // Not sure what this does
RequestItems = new Dictionary<string, KeysAndAttributes> { { dynamoTable, keysAndAttributes } }
};
BatchGetItemResponse result;
do
{
result = await dynamoDbClient.BatchGetItemAsync(request); // Exception gets thrown from here
var responses = result.Responses;
foreach (var tableName in responses.Keys)
{
var tableItems = responses[tableName];
foreach (var item in tableItems)
{
orders.Add(new CustomerOrder
{
CustomerId = int.Parse(item["CustomerId"].N),
DepartmentId = int.Parse(item["DepartmentId"].N),
Order = JsonConvert.DeserializeObject<Order>(item["Order"].S)
});
}
}
// Set RequestItems to the result's UnprocessedKeys and reissue request
request.RequestItems = result.UnprocessedKeys;
} while (result.UnprocessedKeys.Count > 0);
return orders;
}
上面的代码出现 The provided key element does not match the schema
错误。请帮忙!
您不能“在 BatchGetItemRequest 上设置 IndexName”
事实上,您也不能在 GSI/LSI 上使用 GetItem()。 GetItem() 仅适用于 table.
并且 GetItem() 始终需要完整的主键。
使用部分键,您需要执行多个 Query(),每个哈希键一个。
GSI 没有为您做任何事情。作为排序键的部门实际上也没有为您做任何事情,因为我假设 customerId 是唯一的。
更好的结构可能是让 table 定义为主键只有散列键;
我有一个发电机数据库 table CustomerOrders
具有以下字段
- 主分区键:CustomerId(数字)
- 主排序键:DepartmentId(数字)
- 订单(序列化 Json 字符串)
我想在不使用排序键 (DepartmentId) 的情况下在一个请求中查询多个客户。因此,我在 CustomerId 上创建了一个全局二级索引,并想用它来仅使用 CustomerId 进行查询。我看到的文档仅与 运行 批量查询的 BatchGetItemAsync
有关。我看不到在 BatchGetItemRequest 上设置 IndexName 的方法。怎么办?
下面是我目前的代码段:
public async Task<List<CustomerOrder>> GetOrdersAsync(List<int> customerIds)
{
var orders = new List<CustomerOrder>();
var tableKeys = new List<Dictionary<string, AttributeValue>>();
foreach (var x in customerIds)
{
tableKeys.Add(new Dictionary<string, AttributeValue> { { "CustomerId", new AttributeValue { N = x.ToString() } } });
}
var dynamoTable = $"CustomerOrders";
var keysAndAttributes = new KeysAndAttributes
{
AttributesToGet = new List<string> { "CustomerId", "DepartmentId", "Order" },
Keys = tableKeys
};
var request = new BatchGetItemRequest
{
ReturnConsumedCapacity = ReturnConsumedCapacity.INDEXES, // Not sure what this does
RequestItems = new Dictionary<string, KeysAndAttributes> { { dynamoTable, keysAndAttributes } }
};
BatchGetItemResponse result;
do
{
result = await dynamoDbClient.BatchGetItemAsync(request); // Exception gets thrown from here
var responses = result.Responses;
foreach (var tableName in responses.Keys)
{
var tableItems = responses[tableName];
foreach (var item in tableItems)
{
orders.Add(new CustomerOrder
{
CustomerId = int.Parse(item["CustomerId"].N),
DepartmentId = int.Parse(item["DepartmentId"].N),
Order = JsonConvert.DeserializeObject<Order>(item["Order"].S)
});
}
}
// Set RequestItems to the result's UnprocessedKeys and reissue request
request.RequestItems = result.UnprocessedKeys;
} while (result.UnprocessedKeys.Count > 0);
return orders;
}
上面的代码出现 The provided key element does not match the schema
错误。请帮忙!
您不能“在 BatchGetItemRequest 上设置 IndexName”
事实上,您也不能在 GSI/LSI 上使用 GetItem()。 GetItem() 仅适用于 table.
并且 GetItem() 始终需要完整的主键。
使用部分键,您需要执行多个 Query(),每个哈希键一个。
GSI 没有为您做任何事情。作为排序键的部门实际上也没有为您做任何事情,因为我假设 customerId 是唯一的。
更好的结构可能是让 table 定义为主键只有散列键;