Cypher 介紹
- Cypher 介紹:作為Neo4j的查詢語言,“Cypher”是一個描述性的圖形查詢語言,允許不必編寫圖形結構的遍歷代碼對圖形存儲有表現力和效率的查詢。Cypher還在繼續發展和成熟,這也就意味着有可能會出現語法的變化。同時也意味着作為組件沒有經歷嚴格的性能測試。
- 設計的目的:一個人類查詢語言,適合於開發者和在數據庫上做點對點模式(ad-hoc)查詢的專業操作人員(我認為這個很重要)。它的構念是基於英語單詞和靈巧的圖解。
- 思路:Cyper通過一系列不同的方法和建立於確定的實踐為表達查詢而激發的。許多關鍵字如like和order by是受SQL的啟發。模式匹配的表達式來自於SPARQL。正則表達式匹配實現實用Scala programming language語言。
- 與命令式語言的區別:Cypher是一個申明式的語言。對比命令式語言如Java和腳本語言如Gremlin和JRuby,它的焦點在於從圖中如何找回(what to retrieve),而不是怎么去做。這使得在不對用戶公布的實現細節里關心的是怎么優化查詢。
基於知識圖譜的問題系統 主體類 AnswerSearching 框架介紹
class AnswerSearching: def __init__(self): pass # 主要是根據不同的實體和意圖構造cypher查詢語句 def question_parser(self, data): """ 主要是根據不同的實體和意圖構造cypher查詢語句 :param data: {"Disease":[], "Alias":[], "Symptom":[], "Complication":[]} :return: """ pass # 將問題轉變為cypher查詢語句 def transfor_to_sql(self, label, entities, intent): """ 將問題轉變為cypher查詢語句 :param label:實體標簽 :param entities:實體列表 :param intent:查詢意圖 :return:cypher查詢語句 """ pass # 執行cypher查詢,返回結果 def searching(self, sqls): """ 執行cypher查詢,返回結果 :param sqls: :return:str """ pass # 根據不同意圖,返回不同模板的答案 def answer_template(self, intent, answers): """ 根據不同意圖,返回不同模板的答案 :param intent: 查詢意圖 :param answers: 知識圖譜查詢結果 :return: str """ pass 三、 代碼分模塊介紹 在Python中我們使用py2neo進行查詢 首先安裝py2neo,pip install py2neo 連接上neo4j數據庫 from py2neo import Graph graph = Graph("http://localhost:7474", username="neo4j", password="neo4j") 根據不同的實體和意圖構造cypher查詢語句 def question_parser(data): """ 主要是根據不同的實體和意圖構造cypher查詢語句 :param data: {"Disease":[], "Alias":[], "Symptom":[], "Complication":[]} :return: """ sqls = [] if data: for intent in data["intentions"]: sql_ = {} sql_["intention"] = intent sql = [] if data.get("Disease"): sql = transfor_to_sql("Disease", data["Disease"], intent) elif data.get("Alias"): sql = transfor_to_sql("Alias", data["Alias"], intent) elif data.get("Symptom"): sql = transfor_to_sql("Symptom", data["Symptom"], intent) elif data.get("Complication"): sql = transfor_to_sql("Complication", data["Complication"], intent) if sql: sql_['sql'] = sql sqls.append(sql_) return sql 將問題轉變為cypher查詢語句 def transfor_to_sql(label, entities, intent): """ 將問題轉變為cypher查詢語句 :param label:實體標簽 :param entities:實體列表 :param intent:查詢意圖 :return:cypher查詢語句 """ if not entities: return [] sql = [] # 查詢症狀 if intent == "query_symptom" and label == "Disease": sql = ["MATCH (d:Disease)-[:HAS_SYMPTOM]->(s) WHERE d.name='{0}' RETURN d.name,s.name".format(e) for e in entities] # 查詢治療方法 if intent == "query_cureway" and label == "Disease": sql = ["MATCH (d:Disease)-[:HAS_DRUG]->(n) WHERE d.name='{0}' return d.name,d.treatment," \ "n.name".format(e) for e in entities] # 查詢治療周期 if intent == "query_period" and label == "Disease": sql = ["MATCH (d:Disease) WHERE d.name='{0}' return d.name,d.period".format(e) for e in entities ... 執行cypher查詢,返回結果 def searching(sqls): """ 執行cypher查詢,返回結果 :param sqls: :return:str """ final_answers = [] for sql_ in sqls: intent = sql_['intention'] queries = sql_['sql'] answers = [] for query in queries: ress = graph.run(query).data() answers += ress final_answer = answer_template(intent, answers) if final_answer: final_answers.append(final_answer) return final_answers 根據不同意圖,返回不同模板的答案 def answer_template(intent, answers): """ 根據不同意圖,返回不同模板的答案 :param intent: 查詢意圖 :param answers: 知識圖譜查詢結果 :return: str """ final_answer = "" if not answers: return "" # 查詢症狀 if intent == "query_symptom": disease_dic = {} for data in answers: d = data['d.name'] s = data['s.name'] if d not in disease_dic: disease_dic[d] = [s] else: disease_dic[d].append(s) i = 0 for k, v in disease_dic.items(): if i >= 10: break final_answer += "疾病 {0} 的症狀有:{1}\n".format(k, ','.join(list(set(v)))) i += 1 ...