如何将项目添加到列表中?

Posted

技术标签:

【中文标题】如何将项目添加到列表中?【英文标题】:How do i add items to a list? 【发布时间】:2019-11-26 19:22:03 【问题描述】:

我想在我的用户表中的listOfVideosRated[] 列表中添加一个字符串字词。

【问题讨论】:

我认为您需要先获取记录,然后更新记录并推送。 dynamo 中的记录存储为 json 对象,我认为不能修改对象键,只需替换它们即可。我可能错了 【参考方案1】:

如果您可以发布您的架构/解析器映射模板,我可以提供更具体的建议,但我会尽力用您迄今为止发布的内容来回答这个问题。

简单方法

如果您已经拥有现有项目,一种方法是更新现有的 Pairs 并将其传递给您现有的变更。

const existingItem = 
  id: "e5eb02ae-04d5-4331-91e6-11efaaf12ea5",
  Pairs: [['a', 'b'],['c', 'd'],['e', 'f']]


const newPairs = 
  number1: "g",
  number2: "h"


const updateinfo = 
  id: existingItem.id,
  // Note that if existingItem.Pairs is always defined this can be simplified to
  // Pairs: [...existingItem.Pairs, [newPairs.number1, newPairs.number2]]
  Pairs: existingItem.Pairs ?
      [...existingItem.Pairs, [newPairs.number1, newPairs.number2]] : 
      [[newPairs.number1, newPairs.number2]]


try 
  await API.graphql(graphqlOperation (UpdateInfo,  input: updateinfo ))  
  //mutation
  console.log('success')
 
catch (err) 
  console.log(err)

使用 DynamoDB 函数

如果您没有现有项目,或者Pairs 可能很大,则可以使用 AWS DynamoDB 的 list_append 函数。

list_append(操作数,操作数)

这个函数的计算结果是一个添加了新元素的列表。您可以通过颠倒操作数的顺序将新元素附加到列表的开头或结尾。

这是一个使用它的特定突变的示例。

### SDL
type Item 
    id: ID!
    Pairs: [[String]]


input AddPairInput 
    id: ID!
    number1: String!
    number2: String!


type Mutation 
    addPairToItem(input: AddPairInput!): Item!


...rest of schema omitted for brevity 

### Resolver Request Mapping Template

    "version": "2017-02-28",
    "operation": "UpdateItem",
    "key": 
        "id":  "S": "$ctx.args.input.id"
    ,
    "update": 
        ### Note: we also use if_not_exists here so this works if Pairs is not yet defined on the item.
        "expression":"SET Pairs = list_append(if_not_exists(Pairs, :emptyList), :newPair)",
        "expressionValues": 
           
            ":newPair":"L": ["L":["S":"$ctx.args.input.number1",
                                    "S":"$ctx.args.input.number2"]],
            ":emptyList":"L": []
          
        


### Resolver Response Mapping Template
$util.toJson($ctx.result)

这种方式也很好,因为如果其他人更新了 Pairs,您不会覆盖他们的更新。您还可以通过反转 list_append 函数的参数顺序,将新的 Pair 添加到列表的开头。

带有 AWS Amplify 的 DynamoDB 函数

如果您的项目是由 AWS Amplify 生成的,则需要添加 a customer resolver。

第 1 步:向您的架构添加新的变异

### ./amplify/backend/api/<api_name>/schema.graphql
type Item @model 
  id: ID!
  Pairs: [[String]]


type Mutation 
  addPairToItem(input: AddPairToItemInput!): Item!


input AddPairToItemInput 
  id: ID!
  number1: String!
  number2: String!

第 2 步:添加解析器请求映射模板

### ./amplify/backend/api/<api_name>/resolvers/Mutation.addPairToItem.req.vtl

    "version": "2017-02-28",
    "operation": "UpdateItem",
    "key": 
        "id":  "S": "$ctx.args.input.id"
    ,
    "update": 
        "expression":"SET Pairs = list_append(if_not_exists(Pairs, :emptyList), :newPair)",
        "expressionValues":
          
            ":newPair":"L": ["L":["S":"$ctx.args.input.number1","S":"$ctx.args.input.number2"]],
            ":emptyList":"L": []
          
        

第 3 步:添加解析器响应映射模板

### ./amplify/backend/api/<api_name>/resolvers/Mutation.addPairToItem.res.vtl
$util.toJson($ctx.result)

第 4 步:将您的自定义解析器添加到您的 CustomResources 堆栈中

### ./amplify/backend/api/<api_name>/stacks/CustomResources.json
    "Resources": 
        // ...other resources may exist here
        "AddPairToItemResolver": 
            "Type": "AWS::AppSync::Resolver",
            "Properties": 
                "ApiId": 
                    "Ref": "AppSyncApiId"
                ,
                "DataSourceName": "ItemTable",
                "TypeName": "Mutation",
                "FieldName": "addPairToItem",
                "RequestMappingTemplateS3Location": 
                    "Fn::Sub": [
                        "s3://$S3DeploymentBucket/$S3DeploymentRootKey/resolvers/Mutation.addPairToItem.req.vtl",
                        
                            "S3DeploymentBucket": 
                                "Ref": "S3DeploymentBucket"
                            ,
                            "S3DeploymentRootKey": 
                                "Ref": "S3DeploymentRootKey"
                            
                        
                    ]
                ,
                "ResponseMappingTemplateS3Location": 
                    "Fn::Sub": [
                        "s3://$S3DeploymentBucket/$S3DeploymentRootKey/resolvers/Mutation.addPairToItem.res.vtl",
                        
                            "S3DeploymentBucket": 
                                "Ref": "S3DeploymentBucket"
                            ,
                            "S3DeploymentRootKey": 
                                "Ref": "S3DeploymentRootKey"
                            
                        
                    ]
                
            
        
    ,

第 5 步:构建和部署您的新更改

运行 amplify api gql-compile 以查看生成的代码中的新更改(可选)。 运行 amplify push 以部署您的更改。

现在您可以运行 amplify api console 或使用新生成的代码来测试新突变的更改。

要生成新代码,您可以运行 amplify codegen。然后你应该能够做这样的事情

import Amplify,  API, graphqlOperation  from "aws-amplify";
import * as mutations from './graphql/mutations';

// Mutation
const addPairToItem = 
    id: '1',
    number1: 'a',
    number2: 'b'
;

const newItem = await API.graphql(graphqlOperation(mutations.addPairToItem, input: addPairToItem));

其他示例

请记住使用您添加的任何新解析器更新您的 CustomResources.json 文件。

将单个项目添加到标量值列表中

### ./amplify/backend/api/<api_name>/schema.graphql
type Item @model 
    id: ID!
    words: [String]


input AddWordInput 
    id: ID!
    word: String!


type Mutation 
    addWordToItem(input: AddWordInput!): Item!


### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordToItem.req.vtl

    "version": "2017-02-28",
    "operation": "UpdateItem",
    "key": 
        "id":  "S": "$ctx.args.input.id"
    ,
    "update": 
        "expression":"SET words = list_append(if_not_exists(words, :emptyList), :newWord)",
        "expressionValues":
          
            ":newWord":"L": ["S":"$ctx.args.input.word"],
            ":emptyList":"L": []
          
        


### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordToItem.res.vtl
$util.toJson($ctx.result)


### Usage
import Amplify,  API, graphqlOperation  from "aws-amplify";
import * as mutations from './graphql/mutations';

// Mutation
const newWord = 
    id: '1',
    word: 'foo'
;

const newItem = await API.graphql(graphqlOperation(mutations.addWordToItem, input: newWord));

将多个项目添加到标量值列表中

注意:我在这里介绍$util.dynamodb.toDynamoDBJson 是为了更容易构建我们的VTL。到目前为止,我一直很明确,但是这个实用程序可以简化很多工作。 More here

### ./amplify/backend/api/<api_name>/schema.graphql
type Item @model 
    id: ID!
    words: [String]


input AddWordsInput 
  id: ID!
  words: [String!]!


type Mutation 
  addWordsToItem(input: AddWordsInput!): Item!


### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordsToItem.req.vtl

    "version": "2017-02-28",
    "operation": "UpdateItem",
    "key": 
        "id":  "S": "$ctx.args.input.id"
    ,
    "update": 
        "expression":"SET words = list_append(if_not_exists(words, :emptyList), :newWords)",
        "expressionValues":
          
            ":newWords": $util.dynamodb.toDynamoDBJson($ctx.args.input.words),
            ":emptyList": $util.dynamodb.toDynamoDBJson([])
          
        


### ./amplify/backend/api/<api_name>/resolvers/Mutation.addWordsToItem.res.vtl
$util.toJson($ctx.result)


### Usage
import Amplify,  API, graphqlOperation  from "aws-amplify";
import * as mutations from './graphql/mutations';

// Mutation
const newWords = 
    id: '1',
    words: ["bar","xyz","bar"]
;

const newItem = await API.graphql(graphqlOperation(mutations.addWordsToItem, input: newWords));

从标量值列表中删除一项

从 DynamoDB 的列表中删除元素是 done using the REMOVE action。您必须指定一个非负索引作为更新表达式的一部分。如果项目上不存在索引,您的请求不会失败(例如没有索引超出范围异常)。

type Item @model 
    id: ID!
    words: [String]


input RemoveWordInput 
  id: ID!
  wordIndex: Int!


type Mutation 
    removeWordFromItem(input: RemoveWordInput!): Item!


### ./amplify/backend/api/<api_name>/resolvers/Mutation.removeWordFromItem.req.vtl

    "version": "2017-02-28",
    "operation": "UpdateItem",
    "key": 
        "id":  "S": "$ctx.args.input.id"
    ,
    "update": 
        "expression":"REMOVE words[$ctx.args.input.wordIndex]"
    


### ./amplify/backend/api/<api_name>/resolvers/Mutation.removeWordFromItem.res.vtl
$util.toJson($ctx.result)


### Usage
import Amplify,  API, graphqlOperation  from "aws-amplify";
import * as mutations from './graphql/mutations';

// Mutation
const removeWord = 
    id: '1',
    // The index is 0 based so wordIndex: 0
    // would delete the first item,
    // wordIndex: 1 deletes the second, etc.
    wordIndex: 1 
;

const newItem = await API.graphql(graphqlOperation(mutations.removeWordFromItem, input: removeWord));

【讨论】:

@NathanQuinn 我们如何删除?还有我们如何从列表中删除单个项目? list_append 仅连接两个列表,但没有关于如何从列表中删除项目的文档。 @chai86 你的意思是一个标量值列表吗? (例如 ["a", "b", "c]) @Babu 当你说删除时,你的意思是从一个项目中完全删除一个属性吗?当您询问从列表中删除项目时,我理解您的意思,但想了解您的第一个用例。我将发布一些使用其他 DynamoDB 函数的其他示例。 @chai86 我添加了一个将单个标量值和多个标量值添加到列表的示例。这个答案现在变得很长了。我将制作一个包含更多内容的 GitHub 存储库。 非常棒的答案,非常有帮助。希望我能投票更多!

以上是关于如何将项目添加到列表中?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用R [list]将列表的名称插入到列中

如何将mysql内部连接结果从行分组到列

Pandas 将具有多个值的行数据合并到列的 Python 列表中

双向将字符串的“虚拟”列表绑定到列

将多个值添加到列中 - Pandas

python数据库将+1添加到列