AWS Lambda и Dynamo db: как отфильтровать результат сканирования по нескольким параметрам? - PullRequest
1 голос
/ 08 июня 2019

Я новичок в AWS и Dynamo. Я работал над своим проектом с React.js front-end и AWS (Gateway API, Lambda, Dynamo). Это местоположение моего приложения:

https://www.alphaux.com

После нажатия «Получить подсказку» я получаю ответ от сервера. Если я нажимаю на ключевые слова - эти ключевые слова будут добавлены в список параметров GET для запроса, например: тема = л & ключевые слова = blah1, blah2, blah3

Вот детали моей проблемы:

В моей лямбде: .. const docClient = новый AWS.DynamoDB.DocumentClient ({регион: 'us-west-2'}); exports.handler = async (событие) => {..

из GET Я получаю следующие параметры:

const topicName = event.queryParams.topic="React";
const keywords = event.queryParams.topic.keywords="blah1,blah2,blah3";

.. некоторый код здесь преобразует строку ключевых слов в массив:

const keysArray = [blah1, blah2, blah3];

В DynamodB они существуют следующим образом:

[ { "S" : "javascript" }, { "S" : "programming" }, { "S" : "React" } ]

Мой основной ключ раздела: id (номер)

Я пробовал разные способы и подходы, использовал сканирование и запрос - ничего не работает. Я застрял.. Я попробовал следующий подход:

const listToObjectMappings = () => {
    let x = {};
    /* keywords hardcoded for now: */
    const keywords = ["javascript", "React"]; 
    keywords.map(item => x[':' + item] = item)
    return x
}
let mappings = listToObjectMappings()
let joined = Object.keys(mappings).join();

var params2 = {
        TableName : "my-little-table",
        FilterExpression: 'topic = :topic and #keywords IN (' + joined + ')',
            ExpressionAttributeNames: {
              '#keywords' : 'keywords'
        },
        ExpressionAttributeValues:{
            ":topic" : "React"
        }
};
 var params = {
    TableName: "my-little-table",
    FilterExpression: "#topic = :topic",
    ExpressionAttributeNames: {
      "#topic": "topic"
    },
    ExpressionAttributeValues: {
      ":topic": "React"
    }
  };

    let result;
    try {
        /* scan DB */
        result = await docClient.scan(params).promise();
    }
    catch(ex) {
        result = ex;
    }  

Когда я использую «сканирование», результат всегда пуст [], если я пытаюсь использовать «ключевые слова». Он работает только с минимальным значением, например:

    const params = {
        TableName : currentTable,
        FilterExpression:'topic = :topic',
        ExpressionAttributeValues:{
            ":topic" : requestedTopic
        }
    };

.. который дает мне все записи, основанные на requestedTopic.

Если я использую «query», он жалуется, что имя моего ключа («id») слишком короткое и должно иметь длину не менее 3 символов.

Я застрял и изящно прошу вашей помощи! Спасибо!

1 Ответ

1 голос
/ 10 июня 2019

Если вы пытаетесь сопоставить тему и любое из ключевых слов, используйте что-то вроде этого:

const params = {
  TableName: 'mytable',
  FilterExpression: '#tp = :tp AND (contains(#kw, :kw1) OR contains(#kw, :kw2))',
  ExpressionAttributeNames: {
    '#tp': 'topic',
    '#kw': 'keywords',
  },
  ExpressionAttributeValues: {
    ':tp': 'React',
    ':kw1': 'react',
    ':kw2': 'react-router',
  },
};

Если вы пытаетесь сопоставить тему и все ключевые слова, используйте что-то вроде этого:

const params = {
  TableName: 'mytable',
  FilterExpression: '#tp = :tp AND contains(#kw, :kw1) AND contains(#kw, :kw2)',
  ExpressionAttributeNames: {
    '#tp': 'topic',
    '#kw': 'keywords',
  },
  ExpressionAttributeValues: {
    ':tp': 'React',
    ':kw1': 'react',
    ':kw2': 'react-router',
  },
};
...