/// <summary> /// Process an NLPMatchQuestionResponse and turn it into a MatchQuestionLogicResponse containing an answer, /// if any. /// </summary> /// <param name="matchQuestionModel">The NLP model to process.</param> /// <returns>A MatchQuestionLogicResponse containing either 1) nothing if there is no match or 2) the best match if there /// is a match.</returns> public static MatchQuestionLogicResponse ProcessNLPMatchQuestionsResponse(MatchQuestionModelResponse matchQuestionModel) { // Create a "no match" response MatchQuestionLogicResponse nullResponse = new MatchQuestionLogicResponse() { Msg_id = matchQuestionModel.msg_id }; // Check to see whether there is at least a valid answer given if (matchQuestionModel == null || !matchQuestionModel.IsComplete()) { return(nullResponse); } // Collect all questions that might match List <MatchQuestionModelInfo> matchCandidates = new List <MatchQuestionModelInfo>(); foreach (MatchQuestionModelInfo info in matchQuestionModel.possible_matches) { if (info.prob > MatchThreshold) { matchCandidates.Add(info); } } // Call QueryHelperRecursive to get best match that also has an answer return(QueryHelperRecursive(matchCandidates, matchQuestionModel)); }
private void HandleResponse(KeyValuePair <WEBSOCKET_RESPONSE_TYPE, List <BaseModel> > model) { //TODO: what should the websocket do with bad responses? if (model.Key == WEBSOCKET_RESPONSE_TYPE.NONE) { return; } switch (model.Key) { case WEBSOCKET_RESPONSE_TYPE.MATCH_QUESTION: try { { MatchQuestionLogicResponse result = ProcessNLPResponse.ProcessNLPMatchQuestionsResponse(model.Value.Cast <MatchQuestionModelResponse>().ToList().First()); if (result != null) { if (ServerUtilities.msgIdToUserID[result.Msg_id] is NewQuestion) { if (result.Match) { ChatbotWebSocketController.SendAnswerToQuestion(new ChatbotNewAnswerModel(result)); } else { var temp = ProcessChatbotLogic.GenerateModelCompareToOpenQuestions((NewQuestion)ServerUtilities.msgIdToUserID[result.Msg_id]); if (temp != null) { NLPWebSocketController.SendQuestionMatchRequest(temp); } } } else if (ServerUtilities.msgIdToUserID[result.Msg_id] is NewOpenQuestion) { if (result.Match) { ChatbotWebSocketController.SendAnswerToQuestion(new ChatbotNewAnswerModel(result)); } else { int question_id = ProcessChatbotLogic.SaveQuestionToDatabase((NewOpenQuestion)ServerUtilities.msgIdToUserID[result.Msg_id]); String user_id = ((NewOpenQuestion)ServerUtilities.msgIdToUserID[((MatchQuestionModelResponse)model.Value.First()).msg_id]).user_id; ChatbotWebSocketController.SendAnswerToQuestion(new ServerResponseNoAnswerToQuestion(result, (MatchQuestionModelResponse)model.Value.First(), question_id)); ProcessChatbotLogic.AddNewOpenAnswer(user_id, question_id); } } } } } catch (Exception e) { System.Diagnostics.Trace.Write(e.Message); } break; case WEBSOCKET_RESPONSE_TYPE.OFFENSIVENESS: { try { var result = ProcessNLPResponse.ProcessNLPOffensivenessResponse(model.Value.Cast <OffensivenessModelResponse>().ToList().First()); if (result is OffensivenessLogicResponse) { ProcessOffenseResult(result); } } catch (Exception e) { System.Diagnostics.Trace.Write(e.Message); } } break; case WEBSOCKET_RESPONSE_TYPE.NONSENSE: { try { NonsenseLogicResponse result = ProcessNLPResponse.ProcessNLPNonsenseResponse(model.Value.Cast <NonsenseModelResponse>().ToList().First()); if (result is NonsenseLogicResponse) { ProcessNonsenseResult(result); //SendQuestionOffenseRequest((NonsenseLogicResponse)result); } } catch (Exception e) { System.Diagnostics.Trace.Write(e.Message); } } break; } }
/// <summary> /// Recursive function that looks for the best possible match that also has an aswer in the database /// </summary> /// <param name="match_candidates"></param> /// <param name="matchQuestionModel"></param> /// <returns></returns> private static MatchQuestionLogicResponse QueryHelperRecursive(List <MatchQuestionModelInfo> match_candidates, MatchQuestionModelResponse matchQuestionModel) { MatchQuestionModelInfo bestInfo = null; if (match_candidates.Count == 0) { return(new MatchQuestionLogicResponse() { Msg_id = matchQuestionModel.msg_id }); } else { // get best match of all candidates double bestMatch = 0.0; foreach (MatchQuestionModelInfo info in match_candidates) { if (info.prob > bestMatch) { bestInfo = info; bestMatch = info.prob; } } } if (bestInfo == null) { return(new MatchQuestionLogicResponse() { Msg_id = matchQuestionModel.msg_id }); } // Perform query to get the answer to the best match DBManager manager = new DBManager(true); MatchQuestionLogicResponse result = null; StringBuilder sb = new StringBuilder(); sb.Append("SELECT answer "); sb.Append("FROM Answers a, Questions q "); sb.Append($"WHERE q.question_id = {bestInfo.question_id} AND q.answer_id = a.answer_id; "); String sql = sb.ToString(); using (SqlDataReader reader = manager.Read(sql)) { // This query should only return 0 or 1 result if (reader.Read()) { /****/ String sqlSafeAnswer = ServerUtilities.SQLSafeToUserInput(reader.GetString(0)); /****/ result = new MatchQuestionLogicResponse(matchQuestionModel.question_id, matchQuestionModel.msg_id, bestInfo.question_id, true, sqlSafeAnswer); } } manager.Close(); // If a result is found, return the result, else look for another option that does have an answer if (result != null) { return(result); } else { match_candidates.Remove(bestInfo); return(QueryHelperRecursive(match_candidates, matchQuestionModel)); } }