# 导入需要的工具包 from py2neo import Graph, Node, Relationship, NodeMatcher, Subgraph import pandas as pd import numpy as np import os import sys sys.path.append(os.getcwd()) import json from config import neo4j_url,neo4j_username,neo4j_password from pprint import pprint as pp # 连接Neo4j数据库 graph = Graph(neo4j_url, auth=(neo4j_username,neo4j_password) ) def get_initial_path(course_id, platform): course_query = "match(c:`教学课堂`) where c.course_id='{}' return c.course_id".format(course_id) # 查询course_id信息,获取知识森林中课堂信息 course_result = graph.run(course_query).data() # 判断course_id是否存在,如果存在,进行如下查询操作,返回查询结果;如不存在,返回空值 if course_result: # 知识森林查询实训相关节点 shixun_query = '''match(c:`教学课堂`) where c.course_id="{}" match(c)-[:`课堂课程`]->(s:`实践课程`) match(s)-[:`课程章节`]->(st:`章节`) match(st)-[:`章节知识点`]->(kn:`知识点`) match(kn)-[:`知识点实训`]->(shixun:`实训`) return st.stage_id as stage_id,st.stage_name as stage_name, st.stage_sort as stage_sort,kn.knowledge_id as knowledge_id,kn.knowledge as knowledge, shixun.shixun_id as shixun_id,shixun.shixun_name as shixun_name,shixun.link as shixun_link, count(shixun.shixun_id) as shixun_num'''.format(course_id) # 获取实训相关信息,若不存在,为统一处理,返回空DataFrame shixun = graph.run(shixun_query).data() if shixun: # 将查询结果转化为dataframe格式 shixun_data = pd.DataFrame(shixun) else: # 实训结果不存在,赋予一个相同结构的空值 shixun_data = pd.DataFrame(columns=["stage_id","stage_name","stage_sort","knowledge_id", "knowledge","shixun_id","shixun_name","shixun_link","shixun_num"]) # 知识森林查询教学视频相关节点 video_query = '''match(c:`教学课堂`) where c.course_id="{}" match(c)-[:`课堂课程`]->(s:`实践课程`) match(s)-[:`课程章节`]->(st:`章节`) match(st)-[:`章节知识点`]->(kn:`知识点`) match(kn)-[:`知识点视频`]->(video:`教学视频`) return st.stage_id as stage_id, st.stage_name as stage_name, st.stage_sort as stage_sort,kn.knowledge_id as knowledge_id,kn.knowledge as knowledge, video.video_item_id as video_id,video.video_name as video_name,video.link as video_link, count(video.video_item_id) as video_num'''.format(course_id) # 获取教学视频相关信息,若不存在,为统一处理,返回空DataFrame video = graph.run(video_query).data() # 判断获取的教学视频是否为空 if video: # 将教学视频的查询结果转化为dataframe格式 video_data = pd.DataFrame(video) else: # 教学视频为空,返回相同数据结构的空值 video_data = pd.DataFrame(columns=["stage_id","stage_name","stage_sort","knowledge_id", "knowledge","video_id","video_name","video_link","video_num"]) # 知识森林查询教学课件相关节点 att_query = '''match(c:`教学课堂`) where c.course_id="{}" match(c)-[:`课堂课程`]->(s:`实践课程`) match(s)-[:`课程章节`]->(st:`章节`) match(st)-[:`章节知识点`]->(kn:`知识点`) match(kn)-[:`知识点课件`]->(att:`课件`) return st.stage_id as stage_id,st.stage_name as stage_name, st.stage_sort as stage_sort,kn.knowledge_id as knowledge_id,kn.knowledge as knowledge , att.attachment_id as attachment_id,att.filename as filename,att.link as attachment_link, count(att.attachment_id) as attachment_num'''.format(course_id) #获取教学课件相关信息,若不存在,为统一处理,返回空DataFrame att = graph.run(att_query).data() if att: # 将教学课件的查询结果转换成dataframe格式 att_data = pd.DataFrame(att) else: # 教学课件为空,返回相同数据结构的空值 att_data = pd.DataFrame(columns=["stage_id","stage_name","stage_sort","knowledge_id","knowledge", "attachment_id","filename","attachment_link"]) #将三种教学资源合并 merged_data = pd.merge(shixun_data,video_data,on=['stage_id','stage_name',"stage_sort",'knowledge_id', 'knowledge'],how='outer') merged_data = pd.merge(merged_data,att_data,on=['stage_id','stage_name',"stage_sort",'knowledge_id', 'knowledge'],how='outer') # 默认为头歌地址,添加ilearning地址 if platform == '1': merged_data['attachment_link'] = merged_data['attachment_link'].str.replace('www.', 'ilearning.') merged_data['shixun_link'] = merged_data['shixun_link'].str.replace('www.', 'ilearning.') merged_data['video_link'] = merged_data['video_link'].str.replace('www.', 'ilearning.') #对于合并后的结果,对教学资源的数量进行填充 merged_data['shixun_num'].fillna(0,inplace=True) merged_data['video_num'].fillna(0,inplace=True) merged_data['attachment_num'].fillna(0,inplace=True) # 分组获取实训字典 shixun = (merged_data.groupby(['stage_id','stage_name',"stage_sort",'knowledge_id','knowledge', 'shixun_num','video_num','attachment_num']) .apply(lambda x:x[['shixun_id','shixun_name', 'shixun_link']].to_dict('r')) .reset_index(name='shixun')) # 分组获取教学视频字典 video = (merged_data.groupby(['stage_id','stage_name',"stage_sort",'knowledge_id','knowledge', 'shixun_num','video_num','attachment_num']) .apply(lambda x:x[['video_id','video_name', 'video_link']].to_dict('r')) .reset_index(name='video')) # 分组获取教学课件字典 att = (merged_data.groupby(['stage_id','stage_name',"stage_sort",'knowledge_id','knowledge', 'shixun_num','video_num','attachment_num']) .apply(lambda x:x[['attachment_id','filename', 'attachment_link']].to_dict('r')) .reset_index(name='attachment')) # 对分好组的教学资源字典按照章节知识点进行合并 shixun_video = shixun.merge(video,how='outer',on=['stage_id','stage_name',"stage_sort",'knowledge_id', 'knowledge','shixun_num','video_num','attachment_num']) res=shixun_video.merge(att,how='outer',on=['stage_id','stage_name',"stage_sort",'knowledge_id','knowledge', 'shixun_num','video_num','attachment_num']) # 按照知识点进行分组,并命名为知识点 result = (res.groupby(['stage_id','stage_name',"stage_sort"]) .apply(lambda x :x[['knowledge_id','knowledge','shixun_num','video_num','attachment_num', 'shixun','video','attachment']].to_dict('r')) .reset_index(name='knowledge')) # 将最终结果转换成JSON格式 result = json.loads(result.to_json(orient='records',force_ascii=False)) return result else: # 若course_id为空,或者course_id不存在,返回空字典 return {} if __name__ == '__main__': # 读取数据 course_id = "19043" recommend_results = get_initial_path(course_id,'1') pp(recommend_results)