DynamoDb - .NET对象持久性模型 - LoadAsync不应用ScanCondition

时间:2018-03-23 01:27:12

标签: amazon-dynamodb aws-sdk-net

我在这个领域相当新,任何帮助表示赞赏

我在Dynamodb数据库中有一个名为Tenant的表,如下所示: " TenantId"是哈希主键,我没有其他键。我有一个名为" IsDeleted"这是布尔

表格结构

我正在尝试运行查询以获取具有指定" TenantId"的记录。虽然它没有被删除(" IsDeleted == 0")

我可以通过运行以下代码获得正确的结果:(返回0项)

       var filter = new QueryFilter("TenantId", QueryOperator.Equal, "2235ed82-41ec-42b2-bd1c-d94fba2cf9cc");
        filter.AddCondition("IsDeleted", QueryOperator.Equal, 0);

        var dbTenant = await
            _genericRepository.FromQueryAsync(new QueryOperationConfig
            {
                Filter = filter
            }).GetRemainingAsync();

但是当我尝试使用以下代码片段时它没有运气(它返回也被删除的项目)(返回1项)

 var queryFilter = new List<ScanCondition>();
        var scanCondition = new ScanCondition("IsDeleted", ScanOperator.Equal, new object[]{0});
        queryFilter.Add(scanCondition);


        var dbTenant2 = await
            _genericRepository.LoadAsync("2235ed82-41ec-42b2-bd1c-d94fba2cf9cc", new DynamoDBOperationConfig
            {
             QueryFilter   = queryFilter,
             ConditionalOperator = ConditionalOperatorValues.And
            });

任何想法为什么ScanCondition没有效果?

后来我也尝试了这个:(抛出异常)

            var dbTenant2 = await
            _genericRepository.QueryAsync("2235ed82-41ec-42b2-bd1c-d94fba2cf9cc", new DynamoDBOperationConfig()
            {
                QueryFilter = new List<ScanCondition>()
                {
                    new ScanCondition("IsDeleted", ScanOperator.Equal, 0)
                }
            }).GetRemainingAsync();

它抛出:&#34;消息&#34;:&#34;必须为表Tenants定义一个范围键或GSI索引&#34;

为什么会抱怨Range键或索引?我正在打电话

public AsyncSearch<T> QueryAsync<T>(object hashKeyValue, DynamoDBOperationConfig operationConfig = null);

2 个答案:

答案 0 :(得分:0)

你确定'IsDeleted'字段没有空值吗?

答案 1 :(得分:0)

您只是无法查询只提供单个主键(只有散列键)的表。因为该主键只有一个项目。 Query的结果仍然是单个项目,实际上Load操作不是Query。在这种情况下,您只能查询是否有复合主键(Hash(TenantID)和Range Key)或GSI(它不会强加键唯一性,因此在索引上接受重复键)。

第二个代码尝试过滤LoadDynamoDBOperationConfig&#39; s QueryFilter有说明......

    // Summary:
    //     Query filter for the Query operation operation. Evaluates the query results and
    //     returns only the matching values. If you specify more than one condition, then
    //     by default all of the conditions must evaluate to true. To match only some conditions,
    //     set ConditionalOperator to Or. Note: Conditions must be against non-key properties.

因此仅适用于Query次操作

编辑:所以看完你对此的评论......

我认为conditional expressions不适用于读取操作。 AWS文档表明它们适用于putupdate个操作。但是,由于我从来不需要做有条件的Load,所以不能完全确定。一般来说,没有像CheckIfExists这样的功能。您必须阅读该项目并查看它是否存在。条件加载仍将消耗读取吞吐量,因此您唯一的优势就是不会检索它,换句话说就是保存带宽(对于单个项目来说,这是非常微不足道的)。

我的建议是阅读它并在您的应用层中过滤它。不要查询它。但是,您也可以做的是,如果您非常需要,可以使用TenantId作为主题密钥,使用isDeleted作为范围密钥。如果您这样做,您总是需要查询何时想要租客。使用查询,您可以将rangeKey(isDeleted)设置为0或1.这不是我怎么做的。正如我所说,只是阅读它并在我的应用程序中过滤它。

另一个建议可能是在isDeleted字段上设置GSI,并在null时写0。这样,只有1时,您才能在表格中看到该属性。此属性上的GSI称为sparse index。稍后,如果您需要获取所有已删除的租户(isDeleted = 1),您可以无条件地扫描整个索引。当你在0 dynamoDB将它放在索引中的第一个位置时写入null。