Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
160 views
in Technique[技术] by (71.8m points)

amazon web services - Update list items in dynamodb

My data structure in AWS DynamoDB looks like this:

{ key: 'roomNameOne', 
  value: {
    attendees: ['A', 'B', 'C'] // this is a set,
    wsConnections: [{ connectiondId: 'foo', domain: 'xyz.com' }, { connectiondId: 'bar', domain: 'xyz.com' }]
  }
}
{ key: 'roomNameTwo', 
  value: {
    attendees: ['X', 'Y', 'Z'],
    wsConnections: [{ connectiondId: 'foo', domain: 'xyz.com' }, { connectiondId: 'bar', domain: 'xyz.com' }]
  }
}

Now when I get a request that connectionId: foo is lost, I want to remove that entry from all the items.

So after DynamoDB update operation my list should look like this:

{ key: 'roomNameOne', 
  value: {
    attendees: ['A', 'B', 'C'] // this is a set,
    wsConnections: [{ connectiondId: 'bar', domain: 'xyz.com' }]
  }
}
{ key: 'roomNameTwo', 
  value: {
    attendees: ['X', 'Y', 'Z'],
    wsConnections: [{ connectiondId: 'bar', domain: 'xyz.com' }]
  }
}

Can you please help me with the query for update? The trick here is I don't know the room names, but while connection, I am aware of what all room names a connection is interested in.

question from:https://stackoverflow.com/questions/65933123/update-list-items-in-dynamodb

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Unfortunately, DynamoDB does not allow for this type of operation on a complex attribute (e.g. list of maps).

Modeling one-to-many relationships using complex attributes is a useful pattern. However, one of the drawbacks of this approach is that you won't be able to perform the types of operations you're describing.

If you have access patterns that require you to update wsConnections, you might consider modeling the relationship by making each entry of the wsConnections list it's own item in DynamoDB. For example

enter image description here

Storing your data in this way would make it easier for you to remove connections. For example, if you wanted to remove bar from your connections, you could perform the following operation

ddbClient.delete({
    TableName: "YOUR_TABLE_NAME",
    Key: {PK: "roomNameOne", SK: "wsConnection#bar"}
  })

EDIT: If you don't have access to the PK, your only option is a scan operation.

ddbClient.scan({
    "TableName": "YOUR TABLE NAME",
    "FilterExpression": "contains(#key, :value)",
    "ExpressionAttributeValues": {
      ":value": {
        "S": "foo"
      }
    },
    "ExpressionAttributeNames": {
      "#key": "connections"
    }
  })

This will scan the entire database looking for items whose connections attribute contains "foo". This will let you fetch the list of items, which you can then update and persist back to DDB.

This approach is not ideal. The scan operation will search the entire database, which can be horribly inefficient. You'd also have to issue multiple requests to DDB; one to fetch and one to update. multiple roundtrips aren't the end of the world, but again, not ideal.

To unlock more flexible and efficient access patterns, it would be ideal to get the data out of the wsConnections list attribute. As long a the data is buried in a complex attribute, your options will be limited.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...