in lambda/es-proxy-layer/lib/query.js [161:286]
async function get_hit(req, res) {
var query_params = {
question: req.question,
topic: _.get(req, 'session.topic', ''),
from: 0,
size: 1,
minimum_should_match: _.get(req, '_settings.ES_MINIMUM_SHOULD_MATCH'),
phrase_boost: _.get(req, '_settings.ES_PHRASE_BOOST'),
use_keyword_filters: _.get(req, '_settings.ES_USE_KEYWORD_FILTERS'),
keyword_syntax_types: _.get(req, '_settings.ES_KEYWORD_SYNTAX_TYPES'),
syntax_confidence_limit: _.get(req, '_settings.ES_SYNTAX_CONFIDENCE_LIMIT'),
score_answer_field: _.get(req, '_settings.ES_SCORE_ANSWER_FIELD'),
fuzziness: _.get(req, '_settings.ES_USE_FUZZY_MATCH'),
es_expand_contractions: _.get(req,'_settings.ES_EXPAND_CONTRACTIONS'),
kendra_indexes: _.get(req,'_settings.ALT_SEARCH_KENDRA_INDEXES'),
minimum_confidence_score: _.get(req,'_settings.ALT_SEARCH_KENDRA_FAQ_CONFIDENCE_SCORE'),
qnaClientFilter: _.get(req, 'session.QNAClientFilter')
};
var no_hits_question = _.get(req, '_settings.ES_NO_HITS_QUESTION', 'no_hits');
var response = await run_query(req, query_params);
qnabot.log("Query response: ", JSON.stringify(response,null,2));
var hit = _.get(response, "hits.hits[0]._source");
_.set(res, "kendraResultsCached", response.kendraResultsCached);
if (response.kendraResultsCached) qnabot.log(`kendra results cached in res structure`);
_.set(req, "session.qnabotcontext.kendra", response.kendra_context);
if (response.kendra_context) qnabot.log(`kendra context set in res session`);
// ES fallback if KendraFAQ fails
if (!hit && _.get(req, '_settings.KENDRA_FAQ_ES_FALLBACK', true)) {
qnabot.log('ElasticSearch Fallback');
response = await open_es.run_query_es(req, query_params);
if (_.get(response, "hits.hits[0]._source")) {
_.set(response, "hits.hits[0]._source.answersource", "ElasticSearch Fallback");
}
hit = _.get(response, "hits.hits[0]._source");
}
if (hit) {
res['got_hits'] = 1; // response flag, used in logging / kibana
} else if(query_params.kendra_indexes.length != 0) {
qnabot.log("request entering kendra fallback " + JSON.stringify(req))
hit = await kendra_fallback.handler({req,res})
qnabot.log("Result from Kendra " + JSON.stringify(hit))
if(hit && hit.hit_count != 0)
{
_.set(res,"answersource","Kendra Fallback");
_.set(res,"session.qnabot_gotanswer",true) ;
_.set(res,"message", hit.a);
_.set(req,"debug",hit.debug)
res['got_hits'] = 1;
}
}
if(!hit)
{
qnabot.log("No hits from query - searching instead for: " + no_hits_question);
query_params['question'] = no_hits_question;
res['got_hits'] = 0; // response flag, used in logging / kibana
response = await run_query(req, query_params);
hit = _.get(response, "hits.hits[0]._source");
qnabot.log("No hits response: " + JSON.stringify(hit))
}
// Do we have a hit?
if (hit) {
qnabot.log("Setting topic for " + JSON.stringify(hit))
// set res topic from document before running handlebars, so that handlebars can access or overwrite it.
_.set(res, "session.topic", _.get(hit, "t"));
if(_.get(hit, "t")){
if(!res._userInfo){
res._userInfo = {}
}
if(!res._userInfo.recentTopics){
res._userInfo.recentTopics = []
}
res._userInfo.recentTopics.push({
topic: _.get(hit, "t"),
dateTime: (new Date()).toISOString()
})
}
// run handlebars template processing
hit = await handlebars(req, res, hit);
// encrypt conditionalChaining rule, if set
const conditionalChaining = _.get(hit, "conditionalChaining");
if (conditionalChaining) {
qnabot.log("Encrypt conditionalChaining rule to ensure it is tamper proof in session attributes");
const encrypted = encryptor.encrypt(conditionalChaining);
_.set(hit, "conditionalChaining", encrypted);
}
// update the res object with the hit results
res = update_res_with_hit(req, res, hit);
// Call Lambda Hook with args now & override running as middleware step (old behavior)
// This results in:
// - improved predictability of document chaining behavior.. each doc's lambda is run as it is chained
// - autotranslation is now applied to lambda hook responses by default when response is assembled
// optional setting to turn off this behaviour if it causes problems, and revert to old way
if (_.get(req, '_settings.RUN_LAMBDAHOOK_FROM_QUERY_STEP', true)) {// && res['got_hits'] == 1) { //
var lambdaHook = _.get(hit, "l");
if (lambdaHook) {
var payload;
qnabot.log("Invoking Lambda Hook function: ", lambdaHook);
[req, res, payload] = await invokeLambda(lambdaHook, req, res);
// update hit with values returned in res by lambda hook
_.set(hit, "a", _.get(res,"message",""));
var markdown = _.get(res,"session.appContext.altMessages.markdown","");
var ssml = _.get(res,"session.appContext.altMessages.ssml","");
var card = _.get(res,"card",{})
_.set(hit, "alt.markdown", markdown);
_.set(hit, "alt.ssml", ssml);
_.set(hit,"r",card)
}
_.set(hit,"l","") ;
_.set(hit,"args",[]) ;
}
}
return [req, res, hit];
}