简体   繁体   English

使用嵌套集合时,Dynamo DB 查询未返回预期结果

[英]Dynamo DB query not returning expected results when using nested collections

I have an AWS DynamoDB Table with the following structure:我有一个具有以下结构的 AWS DynamoDB 表:

发电机桌

I am trying to get back all the items that have at least one RequestItem with the Id 3401. Here is what I've tried so far (c# code):我正在尝试取回至少包含一个 ID 为 3401 的 RequestItem 的所有项目。这是我迄今为止尝试过的(c# 代码):

     IAmazonDynamoDB client = new AmazonDynamoDBClient(
            new BasicAWSCredentials(configuration["AccessKey"], configuration["SecretKey"]),
            RegionEndpoint.USEast1);

        var request = new ScanRequest
        {
            TableName = "dynamo-table-name",
            ExpressionAttributeNames = new Dictionary<string, string>
            {
                {"#requestItems", "RequestItems"},
                {"#requestId", "Id"}
            },
            ExpressionAttributeValues = new Dictionary<string, AttributeValue>
            {
                {":val", new AttributeValue {N = "3401"}}
            },
            FilterExpression = "contains(#requestItems.#requestId, :val)"
        };
        var response = await client.ScanAsync(request);

I did some variations on FilterExpression (using a simple "=" instead of "contains") but... I still don't get back the results.我对 FilterExpression 做了一些变化(使用简单的“=”而不是“包含”)但是......我仍然没有得到结果。 The query passes without errors, but the result it's an empty list.查询通过而没有错误,但结果是一个空列表。

However, the same code works for properties which are not collections (eg Contact.EmailAddress)但是,相同的代码适用于不是集合的属性(例如 Contact.EmailAddress)

What am I missing?我错过了什么?

[EDIT] [编辑]

I tried another solution that was suggested:我尝试了另一种建议的解决方案:

 var request = new ScanRequest
        {
            TableName = "dynamo-table-name",
            ExpressionAttributeNames = new Dictionary<string, string>
            {
                {"#requestItems", "RequestItems"}
            },
            ExpressionAttributeValues = new Dictionary<string, AttributeValue>
            {
                {
                    ":val",
                    new AttributeValue
                    {
                        L = new List<AttributeValue>
                        {
                            {
                                new AttributeValue
                                {
                                    M = new Dictionary<string, AttributeValue>
                                        {{"Id", new AttributeValue {N = "3401"}}}
                                }
                            }
                        }
                    }
                }
            },
            FilterExpression = "contains(#requestItems, :val)"
        };
        var response = await client.ScanAsync(request);

but I still do not receive results.但我仍然没有收到结果。

You cannot really do the query you want with DynamoDB.您无法真正使用 DynamoDB 执行您想要的查询。 The only thing you could do, if you know the maximum amount of items that could be in RequestItems is to chain together a lot of contains checks with OR : (RequestItems.0.Id = :val) OR (RequestItems.1.Id = :val) OR (RequestItems.2.Id = :val) ... .如果您知道RequestItems中可能contains的最大项目数量,那么您唯一可以做的就是使用OR将大量contains检查链接在一起: (RequestItems.0.Id = :val) OR (RequestItems.1.Id = :val) OR (RequestItems.2.Id = :val) ... . That doesn't seem like a good idea though, unless you know in advance that RequestItems will always contain a certain, low, number of items.不过,这似乎不是一个好主意,除非您事先知道RequestItems将始终包含一定数量的项目。

contains does not work the way you want it to. contains不能按您希望的方式工作。 If you do contains(path, <some number>) , DynamoDB checks if the value found at path is a Set of Numbers and whether the value provided in <some number> is contained within that set.如果您执行contains(path, <some number>) ,DynamoDB 会检查在path找到的值是否是一组数字以及<some number>提供的值是否包含在该组中。

I'm afraid your only option, given your data schema, is to fetch all the items and filter them in your code.鉴于您的数据架构,恐怕您唯一的选择是获取所有项目并在您的代码中过滤它们。

I apologise if this is not authoritative.如果这不是权威,我深表歉意。

I suspect that DynamoDB cannot do that .我怀疑 DynamoDB不能这样做

Moreover, the idea behind DynamoDB is that it should not do that.此外,DynamoDB 背后的想法是它不应该这样做。

DynamoDB does not support arbitrary function evaluation over data. DynamoDB 不支持对数据进行任意函数评估。

DynamoDB is a KV (kinda), store, not a database. DynamoDB 是一个 KV(有点)存储,而不是一个数据库。 The "dynamo" way is to query all the rows (items) you may need and analyse the columns (keys) client-side. “发电机”方式是查询您可能需要的所有行(项目)并在客户端分析列(键)。 Note that it costs exactly same (for dynamo, small difference for traffic), because aws charges you for something like "database disk reads".请注意,它的成本完全相同(对于发电机,流量差异很小),因为 aws 会向您收取“数据库磁盘读取”之类的费用。 And that it's just as cumbersome or easy, for example, you still have to deal with pagination.而且它既繁琐又简单,例如,您仍然必须处理分页。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM