【问题标题】:why my condition expression for attribute not exist fails in dynamodb为什么我的属性条件表达式不存在在 dynamodb 中失败
【发布时间】:2022-04-19 01:55:38
【问题描述】:

我的 DynamoDB 表的主键为 id查询记录会使用相同的id。

现在我想插入一条以idoriginalURL 作为属性的记录,当且仅当表中不存在idoriginalURL 时,我想插入这条记录。

更新:-ConditionExpression: "attribute_not_exists(id) AND attribute_not_exists(originalURL)" 仅适用于主键上下文,according to docs(您可以执行条件放置操作(如果具有指定主键的项不存在,则添加一个新项) ,所以attribute_not_exists(originalURL) 是否存在并没有什么不同。所以我需要一个同时满足条件的解决方案或 originalURL 也可以作为关键

router.post('/', async function (req, res, next) {

  urlId = await nanoid(8);


  //const hashids = new Hashids('this is my salt')
  //urlId=hashids.encode(1)
  console.log('jatin', urlId);
  // urlId=uuidv4();

  const { longURL } = req.body

  const params = {
    TableName: 'url',
    Item: {
      "id": urlId,
      "originalURL": longURL
    },
    UpdateExpression: "set originalURL = :y",
    ConditionExpression: "attribute_not_exists(id) AND attribute_not_exists(originalURL)"
  }
  dynamoDb.put(params, (error, data) => {
    if (error) {
      console.log(error);
      res.status(400).json({ error: error });
    } else if (Object.keys(data).length === 0 && data.constructor === Object) {
      res.status(200).json(
        {
          urlId,
          longURL,
          status: 'success'
        })
    }

    else {
      res.status(400).json({ error: 'Please try again' });
    }
  })
});

到目前为止,即使我尝试使用已经存在的原始 URL 发送请求,它也会成功添加我不想要的记录。

【问题讨论】:

  • 那么urlId也一样吗?在我看来,您正在生成随机的urlId
  • @Marcin 是的,我正在生成随机 urlId,任何记录的 urlId 都不相同,我的条件是仅当 urlID 说 xyz 并且原始 URL 说 google.com 不存在于表中时才添加记录从以前开始,有没有一种方法可以使条件表达式也适用于该 originalURL 属性

标签: node.js amazon-web-services express amazon-dynamodb


【解决方案1】:

对于putItem api,您可以使用条件表达式。根据Doc

条件表达式

一个必须满足的条件才能获得 条件 PutItem 操作成功。

表达式可以包含以下任何内容:

函数:attribute_exists |属性不存在 |属性类型 | 包含 | begin_with |尺寸

这些函数名区分大小写。

比较运算符:= | | | = |之间 |在

逻辑运算符:AND |或 |不是

有关条件表达式的详细信息,请参阅条件 Amazon DynamoDB 开发人员指南中的表达式。

类型:字符串

必填:否

本文档中也解释了相同的场景:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html#Expressions.ConditionExpressions.PreventingOverwrites

PutItem 操作用相同的键覆盖一个项目(如果它 存在)。如果您想避免这种情况,请使用条件表达式。这个 仅当有问题的项目没有时才允许写入继续 已经有相同的密钥了。

aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json \
    --condition-expression "attribute_not_exists(Id)" 

【讨论】:

  • 您的引用是正确的,但它们没有任何用处!因为我的问题与 AND 运算符加入的 2 个条件有关,所以主键属性条件似乎也应该起作用,所以我需要一个同时满足两个条件的解决方案或 originalURL 也充当键
【解决方案2】:

检查是否可以解决问题

import { marshall } from "@aws-sdk/util-dynamodb";

const params = {
    TableName: 'url',
    Item: {
      "id": urlId,
      "originalURL": longURL
    },
    ExpressionAttributeValue: marshal({
       ":originalURL": originalURLVariable
       ":id": idVariable
    }),
    ConditionExpression: "id <> :id AND originalURL <> :originalURL",
    UpdateExpression: "set originalURL = :originalURL",
   }

【讨论】:

猜你喜欢
  • 2018-09-27
  • 2013-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多