Использование AWS Lambda с Elastic Search, получение Undefined из поискового клиента

Я пытаюсь изучить Nodejs, одновременно изучая платформу AWS.

Я создаю приложение Lex, которое использует функцию Lambda с экземпляром AWS Elastic Search.

Мой поиск является базовым и находит то, что ему нужно, дело в том, что когда я тестирую свой обработчик, он не получает данные. Когда я записываю результаты в консоль, кажется, что объект результата поиска не передается обратно в функцию-обработчик до тех пор, пока обработчик уже не напечатает результаты. Используя журналы консоли, я получаю такой вывод:

Starting handler function
Starting search
{ dialogAction:
   { type: 'Close',
     fulfillmentState: 'Fulfilled',
     message: { contentType: 'PlainText', content: undefined  } } }
Top hit: [object Object]

Элемент содержимого не определен, но вместо этого должен быть объектом Top Hit, возвращаемым из search.js. Я вижу, что объект TopHit обнаруживается, но почему функция index.handler печатается до того, как будет возвращен поисковый ответ?

Моя функция Lambda Handler в index.js:

const search = require("./search.js");
exports.handler = (event, context, callback) => {

console.log("Starting handler function");

const questionReq = event.currentIntent.slots.question;
//console.log(questionReq);
// call Exported function from search js.Pass in string as question
const results = search.searchQuestion(questionReq);

const eventResponse = {
    "dialogAction": {
    "type": "Close",
    "fulfillmentState": "Fulfilled",
    "message": {
      "contentType": "PlainText",
      "content": results
    }
  }
};

callback(null, eventResponse);
};

Мой эластичный поиск в search.js:

const client = require('./connection.js');

exports.searchQuestion = function(question)
{
    var topHit = "";
    console.log("Starting search");
    client.search({
      index: 'library',
      type: 'dsa',
      body: {
        query: {
          match: { "q": question }
        },
      }
  }).then(function (resp){
      topHit = resp.hits.hits[0];
      console.log("Top hit: " + topHit);
  }, function(err){
      console.trace(err.message);
  })
    return JSON.stringify(topHit);
}

Спасибо заранее за любые предложения.


person astralbody888    schedule 16.10.2017    source источник
comment
Можете ли вы регистрировать данные в событии? Просто чтобы убедиться, что ваш вопрос определен. Помимо этого, я хотел бы убедиться, что resp.hits.hits возвращает значение, если это не так - вы сделали что-то не так на стороне elasticsearch (вероятно, неправильно индексируются), что, похоже, не входит в область видимости. этого вопроса.   -  person Ramzi C.    schedule 17.10.2017
comment
Если я правильно понимаю, ценность вашего контента должна быть. Я могу ошибаться. Это не определено?   -  person user-developer    schedule 17.10.2017
comment
@RamziC. Хороший вопрос, но когда я регистрирую результаты topHit из search.js, я получаю правильный ответ JSON, так что это не проблема с эластичным поиском, я думаю, это проблема с моим кодом.   -  person astralbody888    schedule 17.10.2017
comment
@chandrasugur Да, вы правы, извините, я дважды проверял назначение topHit и забыл изменить его. В этом случае, когда я использую topHit =, я получаю результат.   -  person astralbody888    schedule 17.10.2017


Ответы (1)


Ваша функция searchQuestion является асинхронной, она возвращает обещание.

Ваш код должен выглядеть примерно так:

const search = require("./search.js");
exports.handler = (event, context, callback) => {
    console.log("Starting handler function");

    const questionReq = event.currentIntent.slots.question;
    //console.log(questionReq);
    // call Exported function from search js.Pass in string as question
    search.searchQuestion(questionReq)
        .then(result => {
            const eventResponse = {
                "dialogAction": {
                    "type": "Close",
                    "fulfillmentState": "Fulfilled",
                    "message": {
                        "contentType": "PlainText",
                        "content": results
                    }
                }
            };
          callback(null, eventResponse);
      });
};

Ваш эластичный поиск в search.js:

const client = require('./connection.js');

exports.searchQuestion = function(question)
{
    return new Promise(function(resolve, reject) {
       var topHit = "";
       console.log("Starting search");
       client.search({
         index: 'library',
         type: 'dsa',
         body: {
           query: {
             match: { "q": question }
          },
        }
     }).then(function (resp){
         topHit = resp.hits.hits[0];
         return resolve(topHit);
     }, function(err){
         console.trace(err.message);
    });
  });
}

Надеюсь, это поможет :).

person NItin Vaja    schedule 17.10.2017
comment
@Nltin Vaja, я думаю, что это правильное направление, но этот код выдает мне ошибку: index.js:16 .then(result => { ^ TypeError: search.searchQuestion(...).then is not a function at Object.exports.handler (index.js:16:10) at Object.<anonymous> (test.js:48:7) Из того, что я вижу, это означает, что мой searchQuestion по-прежнему не возвращает обещание должным образом? Что еще мне не хватает? - person astralbody888; 17.10.2017
comment
Повторите попытку, указанную выше. Кроме того, вы также можете попробовать это - ›return client.search .. который затем должен вернуть это обещание. - person NItin Vaja; 17.10.2017
comment
@Nltin Vaja Вот и все! Спасибо :) - person astralbody888; 17.10.2017
comment
@ astralbody888 Нет проблем, наслаждайся :) - person NItin Vaja; 17.10.2017