выборка данных из DynamoDB с использованием Node.js - PullRequest
0 голосов
/ 01 мая 2020

Я работаю над lex chatbot и пытаюсь получить данные из таблицы DynamoDB, но когда я запускаю код, он выдал ошибку Недопустимое выражение KeyConditionExpression: имя атрибута выражения, используемое в пути к документу, не определено; имя атрибута: #Phone "

вот мой код

'use strict';

///////////////////////////////////////////////Helper functions///////////////////////////////
const getFlightStatus =  (Phone_number, callback) => {
    var AWS = require("aws-sdk");
    var docClient = new AWS.DynamoDB.DocumentClient();
    console.log(`Querying flight status for ${Phone_number}`);

    var params = {
      TableName: "air_stallion",
      KeyConditionExpression: "#Phone = :Phone_number",
      // ExpressionAttributeNames: {
      //   "Phone": "Phone_number"
      // },
      ExpressionAttributeValues: {  
        ":Phone_number": Phone_number,
      }
    };
    docClient.query(params, function (err, data) {
      if (err) {
        console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
      } else {
        console.log("Query succeeded.");
        console.log(data);
        if (data.Count > 0) {
          console.log('returningggg from get query success')
          callback({
              'statusCode': 200,
              'Arrival_city': data.Items[0].Departure_city,
              'Departure_city': data.Items[0].Arrival_city,
              'Date': data.Items[0].Date,
            }
          )
        }
        else {
          console.log('returningggg from get query failer')
          callback ({
            'statusCode': 500,
            'Message': `Account does not exist for account number ${Phone_number}`
          })
        }

      }
    });

}
function spellDigitOutput(number){
    return '<say-as interpret-as="digits">' + number + '</say-as>';
}
////////////////////////////////////////Dialog States for Lex//////////////////////////////////
const elicitSlot = (sessionAttributes, intentName, slots, slotToElicit, message) => {
  return {
    'sessionAttributes': sessionAttributes,
    'dialogAction': {
      'type': 'ElicitSlot',
      'intentName': intentName,
      'slots': slots,
      'slotToElicit': slotToElicit,
      'message': message
    }
  }
}

const delegate = (sessionAttributes, slots) => {
  return {
    'sessionAttributes': sessionAttributes,
    'dialogAction': {
      'type': 'Delegate',
      'slots': slots
    }
  };
};

const close = (sessionAttributes, fulfillmentState, message) => {
  console.log('close state calleddddd', message)
  return {
    'sessionAttributes': sessionAttributes,
    'dialogAction': {
      'type': 'Close',
      'fulfillmentState': fulfillmentState,
      'message': message
    }
  };
};

const confirmIntent = (sessionAttributes, intentName, slots, message) => {
  return {
    'sessionAttributes': sessionAttributes,
    'dialogAction': {
      'type': 'ConfirmIntent',
      'intentName': intentName,
      'slots': slots,
      'message': message
    }
  };
};

///////////////////////////////////////////////Intent Fulfilment codehook///////////////////////////////
var outputDialogMode;
const handleFulfillmentCodeHook = (intentRequest, callback) => {
  var userId = intentRequest.userId;
  const slots = intentRequest.currentIntent.slots;
  var Phone_number = intentRequest.currentIntent.slots.Phone_number;
  return fulfillCheckFlight(Phone_number, fullfiledOrder => {
    console.log('fulfill orderrrrrrrrrrrrr', fullfiledOrder)
    callback(close(intentRequest.sessionAttributes, fullfiledOrder.fullfilmentState, fullfiledOrder.message));
  });
}

const buildFulfilmentResult = (fullfilmentState, messageContent) => {
  console.log('calledd build fulfillement')
  return {
    'fullfilmentState': fullfilmentState,
    'message': { contentType: 'PlainText', content: messageContent }
  };
}

 function fulfillCheckFlight(Phone_number, callback) {
  console.log('fulfilment codehook called')
  return getFlightStatus(Phone_number, (item) => {
    if (item.statusCode == 200) {
      console.log('calling build fulfillement')
      callback(buildFulfilmentResult('Fulfilled', `Thanks, for using our services. Your Flight status is Confirmed ${item.Arrival_city}`));
    }else{
      callback(buildFulfilmentResult('Failed', `No ticket found for phone number ${Phone_number}`));
    }

  });
}



////////////////////////////////Intent Dialogue code hook /////////////////////////////
const handleDialogCodeHook = (intentRequest) => {
  // Perform basic validation on the supplied input slots.
  // Use the elicitSlot dialog action to re-prompt for the first violation detected.

  var userId = intentRequest.userId;
  const slots = intentRequest.currentIntent.slots;
  var confirmationStatus = intentRequest.currentIntent.confirmationStatus;
  var Phone_number = intentRequest.currentIntent.slots.Phone_number;

  const validationResult = validateCheckingFlight(Phone_number);
  if (!validationResult.isValid) {
    slots[`${validationResult.violatedSlot}`] = null;
    return elicitSlot(
      intentRequest.sessionAttributes,
      intentRequest.currentIntent.name,
      slots,
      validationResult.violatedSlot,
      validationResult.message,
    )
  }
  else if(confirmationStatus == 'None'){
    let message;
    if(outputDialogMode == 'Voice'){
      message = {
        'contentType': "SSML",
        'content': `Is this information correct? PhoneNo: ${spellDigitOutput(Phone_number)} .`
      }
    }else{
      message = {
        'contentType': "PlainText",
        'content': `Is this information correct? PhoneNo: ${spellDigitOutput(Phone_number)} .`
      }
    }

    confirmIntent(intentRequest.sessionAttributes,slots,message)
  }
  return delegate(intentRequest.sessionAttributes, slots);

}

const validateCheckingFlight = (Phone_number) => {
   if(Phone_number == null){
    return buildValidationResult(false, 'Phone_number', ` Enter your Phone Number...`);
  }
  else if(Phone_number.toString().length != 12){
    if(outputDialogMode == 'Voice'){
      return buildValidationResult(false, 'PhoneNo', `The PhoneNo ${spellDigitOutput(Phone_number)} is not correct. It should be 12 digits in format ${spellDigitOutput('44XXXXXXXXXX')}`);
    }else{
      return buildValidationResult(false, 'PhoneNo', `The PhoneNo ${spellDigitOutput(Phone_number)} is not correct. It should be 12 digits in format 44XXXXXXXXXX`);
    }

  }
  return buildValidationResult(true, null, null);
}

const buildValidationResult = (isValid, violatedSlot, messageContent) => {
  if (messageContent == null) {
    return {
      "isValid": isValid,
      "violatedSlot": violatedSlot,
    }
  }
  return {
    'isValid': isValid,
    'violatedSlot': violatedSlot,
    'message': { 'contentType': 'PlainText', 'content': messageContent }
  }
}
const buildValidationResultForSSML = (isValid, violatedSlot, messageContent) => {
  if (messageContent == null) {
    return {
      "isValid": isValid,
      "violatedSlot": violatedSlot,
    }
  }
  return {
    'isValid': isValid,
    'violatedSlot': violatedSlot,
    'message': { 'contentType': 'SSML', 'content': messageContent }
  }
}


////////////////////////////////checkingFlight Intent/////////////////////////////
const checkingFlight = (intentRequest, callback) => {
  const source = intentRequest.invocationSource;
  outputDialogMode = intentRequest.outputDialogMode;
  console.log('outputDialogMode',outputDialogMode)
  console.log('intent request', intentRequest)
  // check if it is dialogue code hook or fulfilment codehook
  if (source === 'DialogCodeHook') {
    callback(handleDialogCodeHook(intentRequest));
  }
  if (source === 'FulfillmentCodeHook') {
    handleFulfillmentCodeHook(intentRequest, dialogState => {
      callback(dialogState);
    });
  }

}

////////////////////////////////dispatching which intent is called/////////////////////////////
const dispatch = (intentRequest, callback) => {
  console.log(`dispatch userId=${intentRequest.userId}, intentName=${intentRequest.currentIntent.name}`);
  const intentName = intentRequest.currentIntent.name;

  console.log(intentName + ' was called');
  if (intentName === 'CheckingFlight') {
    checkingFlight(intentRequest, checkingFlightResult => {
      let CheckingFlightResult = checkingFlightResult;
      console.log('checkingFlightResult', checkingFlightResult);
      callback(CheckingFlightResult);
    });

  }
  else{
    throw new Error(`Intent with name ${intentName} not supported`);
  }


};

////////////////////////////////ENTRY POINT/////////////////////////////
module.exports.intents = (event, context, callback) => {
  dispatch(event, res => {
    callback(null, res);
  });
};

пожалуйста, посмотрите на это и скажите мне, в чем проблема.

1 Ответ

0 голосов
/ 01 мая 2020

при использовании #Phone ожидается, что он будет определен в именах атрибутов, например,

{
      TableName: "air_stallion",
      KeyConditionExpression: "#Phone = :Phone_number",
      ExpressionAttributeNames: {
         "#Phone": "Phone_number"
      },
      ExpressionAttributeValues: {  
        ":Phone_number": Phone_number,
      }
    }

проверьте больше об именах атрибутов: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ExpressionAttributeNames.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...