如何在 DynamoDB 中过滤嵌套数组对象

Nar*_*han 6 amazon-dynamodb aws-sdk-nodejs aws-sdk-js

我是 AWS DynamoDB 的初学者,我想使用 SENDTO.emailAddress = "first@first.com" 作为 FilterExpression 扫描 DynamoDB。

数据库结构看起来像这样

{
    ID
    NAME
    MESSAGE
    SENDTO[
        {
            name
            emailAddress
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

样本数据

{
    ID: 1,
    NAME: "HELLO",
    MESSAGE: "HELLO WORLD!",
    SENDTO: [
        {
            name: "First",
            emailAddress: "first@first.com"
        },
        {
            name: "Second",
            emailAddress: "second@first.com"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

我想检索与 emailAddress 匹配的文档。我尝试使用过滤器表达式进行扫描,这是我检索数据的代码。我正在使用 AWS Javascript SDK。

let params = {
    TableName : "email",
    FilterExpression: "SENDTO.emailAddress = :emailAddress",
    ExpressionAttributeValues: {
        ":emailAddress": "first@first.com",
    }
}

let result = await ctx.docClient.scan(params).promise();
Run Code Online (Sandbox Code Playgroud)

not*_*est 6

为了按sendto属性查找项目,您需要知道nameemailAddress属性值。DynamoDB 无法仅通过对象中的某个属性(即仅email属性值)找到数据。

CONTAINS函数可用于查找List数据类型的数据。

列表支持 CONTAINS:当评估“a CONTAINS b”时,“a”可以是列表;但是,“b”不能是集合、映射或列表。

使用 Contains 的示例代码:-

var params = {
    TableName: "email",
    FilterExpression: "contains (SENDTO, :sendToVal)",
    ExpressionAttributeValues: {
        ":sendToVal": {
            "name" : "First",
            "emailAddress" : "first@first.com"
        }
    }
}; 
Run Code Online (Sandbox Code Playgroud)

name如果您不知道和属性的值emailAddress,您可能需要重新建模数据以满足您的用例。

  • 这会比较整个对象,这可能很有用。我们如何只检查地图的某一区域呢? (2认同)

Dmi*_*nko 2

我认为您应该为用户和消息创建两个表。

用户表有partition_key: user_id 和sort_key: email 以及一个包含他的消息id 数组的字段。

消息表有partition_key:message_id 和一个包含用户id 数组的字段。

当您获取用户 ID 数组时,您可以使用BATCH GET查询来获取一条消息的所有用户。

当您获得消息 ID 数组时,您可以使用BATCH GET查询来获取一个用户的所有消息。

如果您想通过电子邮件获取一位用户,您可以使用QUERY方法。

文档