首页 > 解决方案 > 使用全局二级索引从 Dynamo DB 查询数据

问题描述

我正在使用 AWS Amplify 设置无服务器应用程序

我的前端应用程序具有以下代码

import React, { Component } from 'react';
import './App.css';
import Layout from './Containers/Layout';
import { Amplify, API } from 'aws-amplify';
import aws_exports from './aws-exports';

Amplify.configure(aws_exports);
const apiName = 'top3DynamoDBAPI';
let path = '/listings/';
let partitionKey = 'Restaurant';

class App extends Component {
  
  componentDidMount() {
    API.get(apiName, path + partitionKey).then(response => {
      console.log(response)
    });
  }

  state = {
    listings: {
    }
  }
  render() {
    return (
    <div className="App">
      <Layout />
    </div>
    );
  }
}

export default App;

在我的后端 API 中,从表中检索项目的 get 方法如下

/********************************
 * HTTP Get method for list objects *
 ********************************/

app.get(path + hashKeyPath, function(req, res) {
  var condition = {}
  condition[partitionKeyName] = {
    ComparisonOperator: 'EQ'
  }

  if (userIdPresent && req.apiGateway) {
    condition[partitionKeyName]['AttributeValueList'] = [req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH ];
  } else {
    try {
      condition[partitionKeyName]['AttributeValueList'] = [ convertUrlType(req.params[partitionKeyName], partitionKeyType) ];
    } catch(err) {
      res.statusCode = 500;
      res.json({error: 'Wrong column type ' + err});
    }
  }

  let queryParams = {
    TableName: tableName,
    KeyConditions: condition
  }

  dynamodb.query(queryParams, (err, data) => {
    if (err) {
      res.statusCode = 500;
      res.json({error: 'Could not load items: ' + err});
    } else {
      res.json(data.Items);
    }
  });
});

在我的 Dynamo DB 表中,我有一个具有类别的主分区,其中一个名为 'Restaurant' 。所以在我的 App.js 中我设置了一些变量并调用 API 来获取 ComponentDidMount 中的项目

const apiName = 'top3DynamoDBAPI';
let path = '/listings/';
let partitionKey = 'Restaurant';

  componentDidMount() {
    API.get(apiName, path + partitionKey).then(response => {
      console.log(response)
    });

这将返回表中主分区与名为“Restaurant”的值匹配的所有项目

现在我有一个名为“Listing_Location”的全局二级分区,它目前有两个值——悉尼和布里斯班。

后端 API 使用 DynamoDB 的 Document Client,并初始化了以下变量

const userIdPresent = false; // TODO: update in case is required to use that definition
const partitionKeyName = "Listing_Category";
const partitionKeyType = "S";
const sortKeyName = "Listing_Id";
const sortKeyType = "S";
const hasSortKey = sortKeyName !== "";
const path = "/listings";
const UNAUTH = 'UNAUTH';
const hashKeyPath = '/:' + partitionKeyName;
const sortKeyPath = hasSortKey ? '/:' + sortKeyName : '';

我一直在试图弄清楚如何将辅助分区传递到我的后端,以便我可以根据位置查找项目。请你帮忙解决这个问题。

标签: amazon-dynamodbaws-amplifydynamodb-queries

解决方案


我能够结合来自 DynamoDb 如何查询全局二级索引的信息来解决它?https://medium.com/@ole.ersoy/sending-an-email-parameter-with-amplify-api-get-request-4c1c8dc0c952

现在,我的 App.js 看起来像

  componentDidMount() {
    let params = {
      'queryStringParameters': {
        location: 'Brisbane'
      }
    }

    API.get(apiName, path, params).then(response => {
      this.setState({
        listings: response
      })
      console.log(response)
    });
  }

新的get函数是

/* NEW GET ATTEMPT*/
app.get(path, function (req, res) {

  if (userIdPresent) {
    req.body['userId'] = req.apiGateway.event.requestContext.identity.cognitoIdentityId || UNAUTH;
  }

  const location = req.query.location;

  var queryItemParams = {
    TableName: tableName,
    IndexName: "ListingGSI",
    KeyConditionExpression: "#location = :v_location",
    ExpressionAttributeNames: {
      "#location": "Listing_Location"
    },
    ExpressionAttributeValues: {
      ":v_location": location
    }
  };

  dynamodb.query(queryItemParams, (err, data) => {
    if (err) {
      res.statusCode = 500;
      res.json({ error: 'Could not load items: ' + err });
    } else {
      res.json(data.Items);
    }
  });
});

推荐阅读