0

我正在玩 AWS CDK,到目前为止已经实现了 API Gateway,Lambda 函数指向 DynamoDB。到目前为止,我的 POST/GET 基本 lambda 函数都可以正常工作,因为它相当简单。但是,我现在遇到了一个问题,因为我需要一个更具体的 GET 方法。

对于上下文,假设我有一个产品数据库。每条记录具有以下属性:

{
  "id": "0981a086-7c78-4ce1-a1e7-3af641233a46",
  "name": "test product",
  "price": 1.99,
  "tags": ["tag1", "tag2", "tag3"...]
}

我将有一个将传递标签的端点,并且我需要从包含传入列表中的标签的表中获取所有产品。希望这是有道理的。我相信问题在于我对 的错误使用FilterExpression,它目前返回Missing required key 'RequestItems' in params。我的研究表明我可以改用查询,但我认为这不是最好的方法,而且它给了我一些其他错误。所以在我进入兔子洞之前,我想我会寻求帮助。

这是我目前失败的 Lambda:

const db = new AWS.DynamoDB.DocumentClient();
const TABLE_NAME = process.env.TABLE_NAME || "";
const PRIMARY_KEY = process.env.PRIMARY_KEY || "";

async function getProductByTags(event) {
  const { tags } = event; // ["tag2", "tag3"]

  const params = {
    FilterExpression: `contains (tags, ${tags})`,
    TableName: TABLE_NAME
  };
  try {
    const response = await db 
    .batchGet(params)
    .promise();

    return {
      statusCode: 200,
      body: response
    }
  } catch (err) {
    return {
      statusCode: 500,
      body: `Error getting product. ${err.message}`
    }
  }
}

更改batchGetquery给我这个错误:Either the KeyConditions or KeyConditionExpression parameter must be specified in the request

4

1 回答 1

0

使用batchGet,您必须通过主键识别请求的项目。

让我们尝试使用.scan而不是.batchGet.

更新:

您需要对每个值使用逻辑 OR 条件。

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

  const FilterExpresstion = tags.map((tag) => `contains(tags, :v_${tag})`).join(' or ');
  const ExpressionAttributeValues = tags.reduce((obj, tag) => {
     obj[`:v_${tag}`] = tag;
     return obj;
  }, {});
  const params = {
    FilterExpression,
    ExpressionAttributeValues,
    TableName: TABLE_NAME
  };

// {
//   TableName: 'your_table_name',
//   FilterExpression: 'contains(tags, :v_tag1) or contains(tags, :v_tag2)',
//   ExpressionAttributeValues: {
//     ':v_tag1': "tag1",
//     ':v_tag2': "tag2",
//   }
// }
于 2021-05-03T08:50:30.747 回答