使用 .net SDK 查询 DynamoDb 表的正确方法



我正在尝试了解如何使用DataModel在dynamo中查询表。但是,我找到了两种似乎有效的方法,我找不到正在发生的事情的解释或文档,或者它们之间是否有任何区别。

我发现的方法是使用FilterKeyExpression + FilterExpression.有什么区别和正确的做法?

一些例子:

选项 1:

-- 带索引和键

public async Task<List<T>> Find<T>(Guid id)
{
var query = new QueryOperationConfig
{
IndexName = "Table_Id_Index",
Filter = new QueryFilter("TableId", QueryOperator.Equal, id)
};
return await _dynamoDbContext
.FromQueryAsync<T>(query)
.GetRemainingAsync();
}

-- 具有索引、键和额外过滤功能

public async Task<List<T>> Find<T>(Guid id)
{
var query = new QueryOperationConfig
{
IndexName = "Table_Id_Index",
Filter = new QueryFilter("TableId", QueryOperator.Equal, id)
};
query.AddCondition("Deleted", ScanOperator.NotEqual, true);
return await _dynamoDbContext
.FromQueryAsync<T>(query)
.GetRemainingAsync();
}

-- 带 GSI、钥匙和分部

public async Task<List<T>> Find<T>(Guid id, string partitionKey)
{
var query = new QueryOperationConfig
{
IndexName = "GSI_Index",
Filter = new QueryFilter("TableId", QueryOperator.Equal, id)
};
query.AddCondition("PartitionKey", QueryOperator.Equal, partitionKey);
return await _dynamoDbContext
.FromQueryAsync<T>(query)
.GetRemainingAsync();
}

选项 2:

-- 带索引和键

public async Task<List<T>> Find<T>(Guid id)
{
var expressionAttributeValues = new Dictionary<string, DynamoDBEntry>();
expressionAttributeValues.Add(":v_TableId", id);
var queryOperationConfig = new QueryOperationConfig
{
IndexName = "Table_Id_Index",
KeyExpression = new Expression
{
ExpressionStatement = "TableId = :v_TableId"
ExpressionAttributeValues = expressionAttributeValues
}
};
var result = await _dynamoDBContext
.FromQueryAsync<T>(query)
.GetRemainingAsync();
}

-- 具有索引、键和额外过滤功能

public async Task<List<T>> Find<T>(Guid id)
{
var expressionAttributeValues = new Dictionary<string, DynamoDBEntry>();
expressionAttributeValues.Add(":v_TableId", id);
var filterAttributes = new Dictionary<string, DynamoDBEntry>();
filterAttributes.Add(":v_Deleted", true);
var queryOperationConfig = new QueryOperationConfig
{
IndexName = "Table_Id_Index",
KeyExpression = new Expression
{
ExpressionStatement = "TableId = :v_TableId"
ExpressionAttributeValues = expressionAttributeValues
}
FilterExpression = new Expression
{
ExpressionStatement = "Deleted != :v_Deleted"
ExpressionAttributeValues = filterAttributes
};
};
var result = await _dynamoDBContext
.FromQueryAsync<T>(query)
.GetRemainingAsync();
}

-- 带 GSI、钥匙和分部

public async Task<List<T>> Find<T>(Guid id, string partitionKey)
{
var expressionAttributeValues = new Dictionary<string, DynamoDBEntry>();
expressionAttributeValues.Add(":v_TableId", id);
expressionAttributeValues.Add(":v_PartitionKey", partitionKey);
var queryOperationConfig = new QueryOperationConfig
{
IndexName = "GSI_Index",
KeyExpression = new Expression
{
ExpressionStatement = "TableId = :v_TableId and PartitionKey = :v_PartitionKey"
ExpressionAttributeValues = expressionAttributeValues
}
};
var result = await _dynamoDBContext
.FromQueryAsync<T>(query)
.GetRemainingAsync();
}

令人困惑的是,这些选项之间似乎几乎没有区别。AWSSDK 中的注释。DynamoDBv2 程序集似乎提供了最好的文档。尽管 DynamoDb 中的术语"查询筛选条件"特指读取后处理,但您绝对可以应用针对关键属性(并在运行时进行检查)的QueryOperationConfig.Filter。注释指定键属性与非键属性的事实清楚地表明,这些实际上是读取时键表达式"过滤器",而不是真正意义上的读后过滤器。

当然,这与我们对 DynamoDb 查询的一般了解一致:它们以分区为目标。因此,在哈希键上具有单个筛选条件的 QueryOperationConfig 必须以该分区为目标,并且不可能充当读取后筛选器。否则解释它就是假设实际扫描表然后应用过滤器,这对Query没有任何意义。

总而言之:DocumentModel 提供了两个等效的选项 -QueryOperationConfig.KeyExpression选项,它非常清晰,但公开了较低级别的 API,以及QueryOperationConfig.Filter选项,它抽象了它,但混淆了有意义的术语"过滤器"。 如果他们设计了一种KeyExpression类型,可能使用AddHashKeyCondition(...)AddRangeKeyCondition(...)方法,情况会更加清晰。

#region Assembly AWSSDK.DynamoDBv2, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604
// AWSSDK.DynamoDBv2.dll
#endregion
using System.Collections.Generic;
using Amazon.DynamoDBv2.Model;
namespace Amazon.DynamoDBv2.DocumentModel
{
//
// Summary:
//     Query filter.
public class QueryFilter : Filter
{
//
// Summary:
//     Constructs an empty QueryFilter instance
public QueryFilter();
//
// Summary:
//     Constructs an instance of QueryFilter with a single condition. More conditions
//     can be added after initialization.
//
// Parameters:
//   attributeName:
//     Target attribute name
//
//   op:
//     Comparison operator
//
//   values:
//     Attributes to compare
public QueryFilter(string attributeName, QueryOperator op, List<AttributeValue> values);
//
// Summary:
//     Constructs an instance of QueryFilter with a single condition. More conditions
//     can be added after initialization.
//
// Parameters:
//   attributeName:
//     Target attribute name
//
//   op:
//     Comparison operator
//
//   values:
//     Attributes to compare
public QueryFilter(string attributeName, QueryOperator op, params DynamoDBEntry[] values);
//
// Summary:
//     Adds a condition for a specified key attribute that consists of an operator and
//     any number of AttributeValues.
//
// Parameters:
//   keyAttributeName:
//     Target key attribute name
//
//   op:
//     Comparison operator
//
//   values:
//     AttributeValues to compare to
public void AddCondition(string keyAttributeName, QueryOperator op, List<AttributeValue> values);
//
// Summary:
//     Adds a condition for a specified key attribute that consists of an operator and
//     any number of values
//
// Parameters:
//   keyAttributeName:
//     Target key attribute name
//
//   op:
//     Comparison operator
//
//   values:
//     Values to compare to
public void AddCondition(string keyAttributeName, QueryOperator op, params DynamoDBEntry[] values);
//
// Summary:
//     Adds a condition for a specified non-key attribute that consists of an operator
//     and any number of AttributeValues.
//
// Parameters:
//   nonKeyAttributeName:
//     Target non-key attribute name
//
//   op:
//     Comparison operator
//
//   values:
//     AttributeValues to compare to
public void AddCondition(string nonKeyAttributeName, ScanOperator op, List<AttributeValue> values);
//
// Summary:
//     Adds a condition for a specified non-key attribute that consists of an operator
//     and any number of values
//
// Parameters:
//   nonKeyAttributeName:
//     Target non-key attribute name
//
//   op:
//     Comparison operator
//
//   values:
//     Values to compare to
public void AddCondition(string nonKeyAttributeName, ScanOperator op, params DynamoDBEntry[] values);
}
}

相关内容

最新更新