Neo4j 圖數據庫查詢

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
            ...

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章