0

Ich versuche Nodejs zu lernen und gleichzeitig AWS-Plattform zu lernen.AWS Lambda mit Elastic Search verwenden, Undefined vom Such-Client erhalten

Ich erstelle eine Lex-Anwendung, die eine Lambda-Funktion mit einer AWS Elastic Search-Instanz verwendet.

Meine Suche ist grundlegend und findet, was es benötigt, die Sache ist, wenn ich meinen Handler teste, er empfängt die Daten nicht. Wenn ich die Ergebnisse in der Konsole protokolliere, scheint es so, als ob das Suchergebnisobjekt erst dann an die Handlerfunktion zurückgegeben wird, nachdem der Handler die Ergebnisse bereits gedruckt hat. Mit einigen Konsolenprotokollen ich diese Ausgabe:

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

Der Inhalt Artikel ist nicht definiert, sondern stattdessen das Top Hit Objekt sein, das von Search.js zurückgegeben. Ich kann sehen, dass das TopHit-Objekt gefunden wird, aber warum druckt die index.handler-Funktion, bevor die Suchantwort zurückgegeben wird?

Meine Lambda-Handler-Funktion in 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); 
}; 

Mein Elastic Suche in 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); 
} 

Vielen Dank im Voraus für alle Anregungen.

+1

Können Sie die Daten innerhalb des Ereignisses protokollieren? Nur um sicherzustellen, dass Ihre Frage definiert ist. Abgesehen davon würde ich sicherstellen, dass resp.hits.hits einen Wert zurückgibt, wenn es nicht ist - Sie haben auf der Seite elasticsearch etwas falsch gemacht (wahrscheinlich nicht richtig indexieren), was nicht im Bereich zu sein scheint von dieser Frage. –

+1

Wenn ich richtig verstehe, sollte Ihr Inhalt Wert "" "" sein. Ich könnte falsch liegen. Ist das nicht definiert? –

+0

@ RamziC. Gute Frage, aber wenn ich die Ergebnisse von topHit von search.js protokolliere, bekomme ich die korrekte JSON Antwort, also ist es kein Problem mit Elastic Search, ich denke es ist ein Problem mit meinem Code. – astralbody888

Antwort

2

Ihre searchQuestion-Funktion ist asynchron, sie gibt ein Versprechen zurück.

Der Code sollte wie folgt aussehen:

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); 
     }); 
}; 

Ihre Elastic Suche in 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); 
    }); 
    }); 
} 

Ich hoffe, das hilft :).

+0

@Nltin Vaja, ich denke, das ist die richtige Richtung, aber dieser Code gibt mir eine Fehlermeldung: 'index.js: 16 .then (Ergebnis => { ^ Typeerror: search.searchQuestion (.. ..) dann keine Funktion bei Object.exports.handler ist (index.js: 16: 10.) am Objekt (test.js: 48: 7) ' Von dem, was ich sehe, das heißt meine searchQuestion noch gibt kein Versprechen zurück? Was ich sonst noch vermisse? – astralbody888

+1

Bitte versuchen Sie es erneut mit dem obigen Code. Sie können dies möglicherweise auch versuchen -> return client.search .. welches dann das Versprechen zurückgeben sollte. –

+0

@ Nltin Vaja Das ist es! Vielen Dank :) – astralbody888