Dynamo数据库查询过滤器Node.js

时间:2020-01-13 15:24:54

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

通过AWS运行Node.js无服务器后端。

主要目标:过滤并列出所有本地作业(表项),其中包括提供给过滤器的可用服务和邮政编码。

我传递了多个邮政编码和多个可用服务。

data.radius将是一个邮政编码阵列= [ '93901', '93902', '93905', '93906', '93907', '93912', '93933', '93942', '93944', '93950', '95377', '95378', '95385', '95387', '95391' ]

data.availableServices也将是一个数组=这样的['Snow removal', 'Ice Removal', 'Salting', 'Same Day Response']

我正在尝试进行API调用,该调用仅从zipCode提供的邮政编码数组中返回匹配data.radius的项目,而packageSelected则匹配提供了数组data.availableServices

API调用

import * as dynamoDbLib from "./libs/dynamodb-lib";
import { success, failure } from "./libs/response-lib";

export async function main(event, context) {
  const data = JSON.parse(event.body);
  const params = {
    TableName: "jobs",
    FilterExpression: "zipCode = :radius, packageSelected = :availableServices",
    ExpressionAttributeValues: {
      ":radius": data.radius,
      ":availableServices": data.availableServices
    }
  };

  try {
    const result = await dynamoDbLib.call("query", params);
    // Return the matching list of items in response body
    return success(result.Items);
  } catch (e) {
    return failure({ status: false });
  }

是否需要首先映射邮政编码和可用服务的阵列才能使它起作用?

我应该使用比较运算符吗? https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.QueryFilter.html

查询和过滤是否需要排序键值或分区键? (该表具有排序键和分区键,但我想避免在此调用中使用它们)

我不确定100%如何做到这一点,因此,如果有人能指出正确的方向,那将是很棒的,非常感谢!

1 个答案:

答案 0 :(得分:2)

我不确定您的dynamodb-lib所指的是什么,但这是一个示例,说明如何扫描给定值集中的attribute1和不同值集中的attribute2。它使用标准的AWS JavaScript SDK,尤其是高级文档客户端。

请注意,您不能在此处使用相等性(==)测试,而必须使用包含(IN)测试。而且您不能使用query,但必须使用scan

const AWS = require('aws-sdk');

let dc = new AWS.DynamoDB.DocumentClient({'region': 'us-east-1'});

const data = {
  radius: [ '93901', '93902', '93905', '93906', '93907', '93912', '93933', '93942', '93944', '93950', '95377', '95378', '95385', '95387', '95391' ],
  availableServices: ['Snow removal', 'Ice Removal', 'Salting', 'Same Day Response'],
};

// These hold ExpressionAttributeValues
const zipcodes = {};
const services = {};

data.radius.forEach((zipcode, i) => {
  zipcodes[`:zipcode${i}`] = zipcode;
})

data.availableServices.forEach((service, i) => {
  services[`:services${i}`] = service;
})

// These hold FilterExpression attribute aliases
const zipcodex = Object.keys(zipcodes).toString();
const servicex = Object.keys(services).toString();

const params = {
  TableName: "jobs",
  FilterExpression: `zipCode IN (${zipcodex}) AND packageSelected IN (${servicex})`,
  ExpressionAttributeValues : {...zipcodes, ...services},
};

dc.scan(params, (err, data) => {
  if (err) {
    console.log('Error', err);
  } else {
    for (const item of data.Items) {
      console.log('item:', item);
    }
  }
});