Запрос данных из Dynamo DB с использованием глобального вторичного индекса - PullRequest
0 голосов
/ 21 июня 2020

Я устанавливаю бессерверное приложение, используя 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;

в моем backend 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 у меня есть основной раздел, в котором есть категории, и одна из них называется «Ресторан». Итак, в моем приложении. js я устанавливаю некоторые переменные и вызываю API, чтобы получить элементы в ComponentDidMount

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

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

, это возвращает все элементы из таблицы, где основной раздел соответствует значению под названием «Ресторан».

Теперь у меня есть глобальный вторичный раздел под названием «Listing_Location», который в настоящее время имеет два значения - Sydney и Brisbane.

Серверный API использует клиент документа DynamoDB и инициализировал следующую переменную

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 : '';

Я застрял в попытке выяснить, как передать вторичный раздел моему бэкэнду, чтобы я мог искать элементы в зависимости от их местоположения. Не могли бы вы помочь с этим.

1 Ответ

0 голосов
/ 21 июня 2020

Мне удалось решить эту проблему с помощью комбинации информации из DynamoDb, как запросить глобальный вторичный индекс? и https://medium.com/@ole.ersoy / send-an-email-parameter-with-ampify- api-get-request-4c1c8dc0c952

Теперь мое приложение. 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);
    }
  });
});
...