def calcTasks(data_hub_host_name, data_hub_port, graph_host): url = "bolt://{}:7687".format(graph_host) print('................using graph host {}'.format(graph_host)) print('................. using datahub host {}'.format( data_hub_host_name)) ret_val = [] graph = Graph(url) strategies = graph.nodes.match('Strategy') for strategy in strategies: jobs = graph.match((strategy, ), r_type='EVAL') for j in jobs: deps = [] job_node = j.end_node dependencies = graph.match((job_node, ), r_type="USES") for dependency in dependencies: datahub_url = "{}://{}:{}/{}".format( "arctic", data_hub_host_name, data_hub_port, dependency.end_node['path']) deps.append( DatahubRequirement(name=dependency.end_node['name'], t=0, url=datahub_url)) ret_val.append( CalculationTask(dueBy=job_node['due_by'], requirements=deps, strategy=strategy['name'], eval_label=job_node['name'])) return ret_val
def main(): bolt_url = default(prompt('bolt url(default=bolt://localhost:7687): '), 'bolt://localhost:7687') username = default(prompt('username(defalt=neo4j): '), 'neo4j') password = prompt('password: '******'MATCH (n) DETACH DELETE n') tx = graph.begin() alice = Node("Person", name="Alice") tx.create(alice) bob = Node("Person", name="Bob") relationship = Relationship(alice, "KNOWS", bob) tx.create(relationship) tx.commit() for rel in graph.match(start_node=alice, rel_type="KNOWS"): print(rel.end_node()["name"]) print(graph.exists(relationship)) a = graph.find_one(label="Person", property_key="name", property_value="Alice") r = graph.match_one(start_node=a, rel_type="KNOWS") print(r.end_node()['name'])
def getTestedNeo4jDB(graphDBurl, graphDbCredentials): '''Gets a Neo4j url and returns a GraphDatabaseService to the database after having performed some trivial tests''' try: if graphDbCredentials: authenticate(*graphDbCredentials) graphDb = Graph(graphDBurl) #just fetch a Node to check we are connected #even in DRY RUN we should check Neo4j connectivity #but not in OFFLINE MODE if not OFFLINE_MODE: _ = iter(graphDb.match(limit=1)).next() except StopIteration: pass except SocketError as ex: raise DbNotFoundException(ex, "Could not connect to Graph DB %s." % graphDBurl) if not DRY_RUN and not OFFLINE_MODE: try: test_node = Node("TEST", data="whatever") graphDb.create(test_node) graphDb.delete(test_node) except Exception as ex: raise DBInsufficientPrivileges(\ "Failed on trivial operations in DB %s." % graphDBurl) return graphDb
def getTestedNeo4jDB(graphDBurl, graphDbCredentials): '''Gets a Neo4j url and returns a GraphDatabaseService to the database after having performed some trivial tests''' try: if graphDbCredentials: authenticate(*graphDbCredentials) graphDb = Graph(graphDBurl) #just fetch a Node to check we are connected #even in DRY RUN we should check Neo4j connectivity #but not in OFFLINE MODE if not OFFLINE_MODE: _ = iter(graphDb.match(limit=1)).next() except StopIteration: pass except SocketError as ex: raise DbNotFoundException( ex, "Could not connect to Graph DB %s." % graphDBurl) if not DRY_RUN and not OFFLINE_MODE: try: test_node = Node("TEST", data="whatever") graphDb.create(test_node) graphDb.delete(test_node) except Exception as ex: raise DBInsufficientPrivileges(\ "Failed on trivial operations in DB %s." % graphDBurl) return graphDb
def search_drug(disease_name): graph = Graph(host="52.15.135.11", username="******", password="******") disease = graph.run("MATCH (a) WHERE a.name={x} AND a.label={y} RETURN *", x=disease_name, y="Disease").evaluate() if disease == None: print("There is no such disease") ### add some action to deal with the error, use return now return match_relation = graph.match(start_node=disease) drug_list = [] for i in match_relation: drug_name = i.end_node()["name"] count = i["count"] drug_list.append({"name": drug_name, "use_time": count}) drug_list_sort_by_count = sorted(drug_list, key=lambda e: e.__getitem__("use_time"), reverse=True) print( "The most probobal drugs for {}: (Sorted by the using frequency from high to low)" .format(disease_name)) for drug in drug_list_sort_by_count: print(drug["name"]) return drug_list_sort_by_count
class NeoProvider(object): def __init__(self): # TODO read this from a config file uri = "http://*****:*****@localhost:7474/db/data" self.graph = Graph(uri) self.store = Store(self.graph) def get_start_screen(self): # Fetch the start node start_node = self.graph.find_one("screen", "start", True) # Find all the navigations from the start node nav_rels = self.graph.match(start_node, "nav") # Find all the assets for the start node asset_rels = self.graph.match(start_node, "hasAsset") # Construct the DTOs assets = [Asset(asset_rel.end_node) for asset_rel in asset_rels] navs = [Navigation(nav_rel) for nav_rel in nav_rels] start_screen = Screen(start_node, navs, assets) return start_screen def get_next_screen(self, current_screen_key, option): # Fetch the current node current_node = self.graph.find_one("screen", "id", current_screen_key) # Navigate to the next node via option current_rels = self.graph.match(current_node, "nav") selected_rel = [rel for rel in current_rels if rel.properties['opt'] == int(option)][0] next_node = selected_rel.end_node # Grab new navigations and assets for the next node next_nav_rels = self.graph.match(next_node, "nav") asset_rels = self.graph.match(next_node, "hasAsset") # Construct the DTOs assets = [Asset(asset_rel.end_node) for asset_rel in asset_rels] navs = [Navigation(nav_rel) for nav_rel in next_nav_rels] next_screen = Screen(next_node, navs, assets) return next_screen
def fetch_related_videos(video_id, id_type="videoId", result_len=10): mongo_db = mongo.db neo4j_db = Graph(user=config.neo4j_user, password=config.neo4j_pass) # Find node corresponding to current video source_node = neo4j_db.find_one("Video", id_type, video_id) if id_type == "mongoId": video_id = source_node["videoId"] # Get all edges from current node rel_edges = [rel for rel in neo4j_db.match(start_node=source_node)] # Loop through each edge and update score of end node edge_end_nodes = {} for x in rel_edges: if x.type() == "SameChannel": weight = 5 elif x.type() == "CommonTags": weight = 3 * x["weight"] elif x.type() == "CommonDesc": weight = x["weight"] mongo_id = (x.end_node())["mongoId"] related_id = (x.end_node())["videoId"] if related_id in edge_end_nodes: edge_end_nodes[related_id]["weight"] += weight else: edge_end_nodes[related_id] = { "mongoId": mongo_id, "weight": weight } # Add click log weightage to above score if session.get("user_name"): log_res = VideoLog.query.filter_by(user_name=session.get("user_name"), current_video=video_id).all() for x in log_res: related_video_id = x.clicked_video if related_video_id in edge_end_nodes: edge_end_nodes[related_video_id]["weight"] += 2 # Construct array of related videos from above found nodes related_nodes = [{ "videoId": x, "mongoId": edge_end_nodes[x]["mongoId"], "weight": edge_end_nodes[x]["weight"] } for x in edge_end_nodes] # Filter top weighted nodes to get most relevant videos related_nodes.sort(key=lambda x: x["weight"], reverse=True) related_nodes = related_nodes[:result_len] # Fetch data of these videos from MongoDB mongo_ids = [ObjectId(x["mongoId"]) for x in related_nodes] related_videos = list( mongo_db.videos.find({"_id": { "$in": mongo_ids }}, doc_list_projection)) # Sort the fetched documents using score found above for x in related_videos: x["weight"] = edge_end_nodes[x["id"]]["weight"] related_videos.sort(key=lambda x: x["weight"], reverse=True) return related_videos
def get_cities(province): graph = Graph(host='127.0.0.1', http_port=7474, user='******', password='******') province = graph.find_one('province', property_key='name', property_value=province) if not province: return [] rel = list(graph.match(rel_type='LOCATED_IN', end_node=province)) return [r.start_node()['name'] for r in rel]
def search_disease_and_drug(symptom_list): graph = Graph(host="52.15.135.11", username="******", password="******") disease_list_total = [] for symptom_name in symptom_list: symptom = graph.run( "MATCH (a) WHERE a.name={x} AND a.label={y} RETURN *", x=symptom_name, y="Symptom").evaluate() if symptom == None: print("There is no such disease") ### add some action to deal with the error, use continue now continue match_relation = graph.match(start_node=symptom) disease_list = [] for i in match_relation: disease_name = i.end_node()["name"] count = i["count"] disease_list.append({"name": disease_name, "use_time": count}) disease_list_sort_by_count = sorted( disease_list, key=lambda e: e.__getitem__("use_time"), reverse=True) n = 0 for dis in disease_list_sort_by_count: disease_list_total.append(dis["name"]) n += 1 if n == 3: ##could be larger break final_disease_dict = {} for item in disease_list_total: final_disease_dict.update({item: disease_list_total.count(item)}) disease_final_sort = sorted(final_disease_dict.items(), key=lambda d: d[1], reverse=True) print(disease_final_sort) prob_rank = 1 for (dis, val) in disease_final_sort: print("The probability disease rank {}: {}".format(prob_rank, dis)) most_prob = dis break drug_list = search_drug(most_prob) return most_prob, drug_list
def check_for_relation(node1, node2): graph = Graph('http://localhost:7474/db/data', user='******', password='******') #neo4j_transaction = graph.begin() #******************** TYPE ONE METHOD ***************************# #neo4j_transaction.append(" MATCH (n:Word)-[:CO_OCCURENCED]->(m:Word) RETURN n", n=node1, m=node2) #************************ TYPE TWO NEO$J ************************# selector = NodeSelector(graph) selected1 = selector.select("Word", value=node1) selected2 = selector.select("Word", value=node2) #********************* TYPE 3 NEO$j ****************************# #selected1 = Node("Word",value=node1) #selected2 = Node("Word",value=node2) #selected1 = graph.run("MATCH (a:Word) WHERE a.value={b} RETURN a.value", b=node1) #selected2 = graph.run("MATCH (a:Word) WHERE a.value={b} RETURN a.value", b=node2) print(selected1) print(selected2) #print(dir(selected1.values)) #ab = Relationship(selected1, "CO_OCCURENCED", selected2, bidirectional=True) #print(ab) #neo4j_transaction.commit() #result = neo4j_transaction.commit() #result = graph.exists(ab) #******************* TYPE 4 **********************************# res = graph.match(start_node=selected1, end_node=selected2) print(res) #print(result) if not res: print("HAI") neo4j_transaction = graph.begin() #***************************** TYPE ONE INSERT **************# #neo4j_transaction.append(" CREATE (n:Word{value:{a}})-[r:CO_OCCURENCED]->(m:Word{value:{b}}) RETURN r", n=node1, m=node2, a=node1, b=node2) #***************************** TYPE 3 INSERT *****************# """selected1 = Node("Word",value=node1) selected2 = Node("Word",value=node2) ab = Relationship(selected1, "CO_OCCURENCED", selected2, bidirectional=True) neo4j_transaction.create(ab) neo4j_transaction.commit() result = graph.exists(ab) print(result)""" #result = neo4j_transaction.commit() return 1
def get_graph(): graph = Graph() nodes = set() links = [] for rel_type in [REL_FOLLOWS, REL_UPLOADED, REL_FAVORITED]: for rel in graph.match(rel_type=rel_type): start = node_to_id(rel.start_node) end = node_to_id(rel.end_node) if rel_type == REL_FAVORITED and end not in nodes: continue nodes.add(start) nodes.add(end) links.append([start, end]) return {'nodes': list(nodes), 'links': links}
class AgoraOrganization(object): def __init__(self): self.name = None self.unique_id = None self.mission_statement = None self.email = None self.is_open = False self.is_invite_only = False self.website = None self.graph_db = Graph() @property def org_node(self): return self.graph_db.find_one(AgoraLabel.ORGANIZATION, property_key='name', property_value=self.name) @property def org_members(self): """ list of the members of the organization :return: list of tuple of member name, email """ org_members_nodes = self.graph_db.match(start_node=self.org_node, rel_type=AgoraRelationship.MEMBER_OF, end_node=None) org_members_list = [] for item in org_members_nodes: org_members_list.append((item.end_node["name"], item.end_node["email"])) return org_members_list def create_organization(self): """ create a new organization :return: py2neo Node """ self.unique_id = str(uuid.uuid4()) new_org_properties = { "name": self.name, "mission_statement": self.mission_statement, "unique_id": self.unique_id, "email": self.email, "is_open": self.is_open, "is_invite_only": self.is_invite_only, "website": self.website} new_org_node = Node.cast(AgoraLabel.ORGANIZATION, new_org_properties) self.graph_db.create(new_org_node) return new_org_node
def city(): location = request.args['meetup_group'] graph = Graph(host=config['neo4j']['host'], user=config['neo4j']['user'], password=config['neo4j']['password']) logger.info('Finding upcoming meetup events in {}'.format(location)) groups_data = defaultdict() groups = graph.find('Group') for group in groups: groups_data[group.properties['name']] = [] for rel in graph.match(start_node=group, rel_type="HAS EVENT"): groups_data[group.properties['name']].append(rel.end_node().properties['time']) return json.dumps(groups_data)
def check_for_relation(node1, node2): g = Graph('http://localhost:7474/db/data', user='******', password='******') d = g.run("MATCH (a:Word) WHERE a.value={b} RETURN a", b=node1) list_d = list(d) if len(list_d) > 0: d = list_d[0]['a'] # (f0a4f80:Word {value:"cat",word_count:1}) else: neo4j_transaction = g.begin() d = Node("Word", value=node1, word_count=1) neo4j_transaction.create(d) neo4j_transaction.commit() e = g.run("MATCH (a:Word) WHERE a.value={b} RETURN a", b=node2) list_e = list(e) if len(list_e) > 0: e = list_e[0]['a'] # (f0a4f80:Word {value:"cat",word_count:1}) else: neo4j_transaction = g.begin() e = Node("Word", value=node2, word_count=1) neo4j_transaction.create(e) neo4j_transaction.commit() relations = g.match(start_node=d, rel_type="CO_OCCURENCED", end_node=e) existing_relation = list(relations) if len(existing_relation) == 0: print("No Relationship exists") neo4j_transaction = g.begin() ab = Relationship(d, "CO_OCCURENCED", e, count=1, bidirectional=True) neo4j_transaction.create(ab) neo4j_transaction.commit() else: relation_update = existing_relation[0] #print(relation_update) present_count = relation_update['count'] #print(present_count) new_count = int(present_count) + 1 #print(new_count) #neo4j_transaction = g.begin() # No need of transaction before updating the count relation_update["count"] = new_count # return the updated value relation_update.push() #neo4j_transaction.commit() return 1
def calcPR(): # print('start') # fo = open("graph.txt", "w") graph = Graph('bolt://47.113.103.137:10087', auth=('neo4j', 'pedia_search')) G = nx.DiGraph() node_matcher = NodeMatcher(graph) nodes = node_matcher.match('Entry').all() for node in nodes: G.add_node(node['page_id']) print("node page_id: ",node['page_id']) print("number of nodes: ",G.number_of_nodes()) relationships = graph.match(nodes=None, r_type= 'linkTo', limit=None).all() i = 0 print('start loop') for relationship in relationships: i = i + 1 print(i) print(relationship) start = relationship.start_node['page_id'] end = relationship.end_node['page_id'] print('edge: ',start,' -> ',end) G.add_edge(*(start,end)) print('start pagerank') result = nx.pagerank(G, alpha=0.85, personalization=None, max_iter=20000, tol=1e-06, weight='weight', dangling=None) print(result) print(sorted(result.items(), key=lambda kv: (kv[1], kv[0]))) i = 0 transaction = graph.begin() for cur_page_id in result: i = i + 1 weight = result[cur_page_id] print("node:",i,cur_page_id,weight) matcher = NodeMatcher(graph) node = matcher.match(page_id = cur_page_id).first() # 操作 node['weight'] = weight # 修改weight transaction.push(node) transaction.commit()
def before_all(context): # import falcon_test # context.attachment_dir = os.path.join(os.path.dirname(falcon_test.__file__), 'tests/data') # context.sms_path = os.path.join(os.path.dirname(falcon_test.__file__), '../../var/sms/') # context.mail_path = os.path.join(os.path.dirname(falcon_test.__file__), '../../var/mail/') # clear database graph_db = Graph(settings.DATABASE_URL) # graph_db.delete_all() new_user_node = graph_db.find_one('USER', property_key='email', property_value='*****@*****.**') graph_db.delete(new_user_node) interest_node = graph_db.find_one('INTEREST', property_key='name', property_value=PERSONAS['interest']['name']) interest_relationships = graph_db.match(start_node=None, rel_type='INTERESTED_IN', end_node=interest_node) for relationship in interest_relationships: graph_db.delete(relationship) graph_db.delete(interest_node) context.base_url = "http://localhost:8000" benv.before_all(context)
class SampleNeo(object): def __init__(self): self.graph = Graph("localhost", username="******", password="******") pass def __del__(self): pass def insert_data(self): u1 = Node(label="Person", name="Mengfei") u2 = Node(label="Person", name="Xidong") self.graph.create(u1) self.graph.create(u2) b1 = Node(label="Beer", name="IPA") b2 = Node(label="Beer", name="Rosee") self.graph.create(b1) self.graph.create(b2) r1 = Relationship(u1, "likes", b1) r1['count'] = 1 r2 = Relationship(u2, "likes", b2) r2['count'] = 1 r3 = Relationship(u1, "friends", u2) r3['count'] = 1 self.graph.create(r1) self.graph.create(r2) self.graph.create(r3) def search_data(self): nodes = self.graph.nodes.match(label="Person") node = nodes.first() # rel = self.graph.run("MATCH p=()-->() RETURN p LIMIT 25") rel = self.graph.match([node], ["likes"]) print(rel.first()) for i in rel: print(i)
class Meeting(object): def __init__(self): """ :return: """ self.id = '' self.name = '' self.description = '' self.where = '' self.date = '' self.time = '' self.created_date = '' self.is_recurring = False self._graph_db = Graph(settings.DATABASE_URL) @property def meeting_properties(self): """ :return: """ properties_dict = dict(self.__dict__) del properties_dict['_graph_db'] return properties_dict @property def meeting_node(self): """ :return: """ if self.id != '': return self._graph_db.find_one(GraphLabel.MEETING, property_key='id', property_value=self.id) @property def group(self): """ :return: Group() that is attached to this meeting """ meeting_group_relationship = self._graph_db.match(start_node=None, rel_type=GraphRelationship.HAS_MEETING, end_node=self.meeting_node) group = Group() for rel in meeting_group_relationship: group.id = rel.end_node.properties['id'] group.get_group() return group def set_meeting_properties(self, meeting_properties): """ :param meeting_properties: :return: """ for key, value in meeting_properties.iteritems(): setattr(self, key, value) # @staticmethod def get_meeting(self): """ :return: """ meeting_node = self.meeting_node if meeting_node is not None: meeting_properties = dict(meeting_node.properties) for key, value in meeting_properties.iteritems(): setattr(self, key, value) def create_meeting(self, group_id, meeting_properties=None): """ :param meeting_properties: :return: """ #TODO exception handling self.created_date = datetime.date.today() self.id = str(uuid.uuid4()) if meeting_properties is not None: self.set_meeting_properties(meeting_properties) new_meeting_node = Node.cast(GraphLabel.MEETING, self.meeting_properties) try: self._graph_db.create(new_meeting_node) group = Group() group.id = group_id group_node = group.group_node meeting_group_relationship = Relationship(group_node, GraphRelationship.HAS_MEETING, self.meeting_node) self._graph_db.create_unique(meeting_group_relationship) except: pass return new_meeting_node def update_meeting(self): """ :return: """ meeting_node = self.meeting_node meeting_properties = dict(self.meeting_properties) for key, value in meeting_properties.iteritems(): meeting_node[key] = value meeting_node.push() @property def attendees(self): """ :return: list of attendees dictionaries. these are the users who are attending the meeting """ #TODO get attendees return [] def allow_edit(self, auth_key): """ check if the user is a creator or moderator for the group attached to the meeting :param auth_key: :return: """ allow = False group = self.group moderators = group.group_moderators creator = dict(group.group_creator) if auth_key == creator['id']: allow = True else: for mod in moderators: if auth_key == mod['id']: allow = True return allow def meeting_for_json(self, auth_key): root = dict(self.meeting_properties) root['groups'] = dict(self.group.group_properties) root['attendees'] = self.attendees root['allow_edit'] = self.allow_edit(auth_key=auth_key) return root
class GraphDatabase(): def __init__(self): try: self.graph = Graph( 'http://*****:*****@localhost:7474/db/data') except: print 'ERROR: Initialize Neo4j browser' self.graph.delete_all() def createDocumentNode(self, index, label): docNode = self.graph.merge_one('Document', 'name', 'Doc ' + str(index)) self.updateNode(docNode, { 'id': index, 'label': label, 'in-weight': 0, 'out-weight': 0 }) return docNode def createFeatureNode(self, index, word): wordNode = Node('Feature', word=word) self.graph.create(wordNode) self.updateNode(wordNode, { 'in-weight': 0, 'out-weight': 0, 'id': index }) return wordNode def getFeatureNode(self, word): return list( self.graph.find('Feature', property_key='word', property_value=word))[0] def createWeightedRelation(self, node1, node2, relation): match = self.graph.match(start_node=node1, rel_type=relation, end_node=node2) numberOfRelations = sum(1 for x in match) if numberOfRelations >= 1: match = self.graph.match(start_node=node1, rel_type=relation, end_node=node2) for relationship in match: self.increaseWeight(relationship) self.increaseWeight(node1, 'out-weight') self.increaseWeight(node2, 'in-weight') else: newRelation = Relationship(node1, relation, node2, weight=1) self.graph.create(newRelation) self.increaseWeight(node1, 'out-weight') self.increaseWeight(node2, 'in-weight') def increaseWeight(self, entity, weight='weight'): entity[weight] = entity[weight] + 1 self.graph.push(entity) def updateNode(self, node, propertyDict): node.properties.update(propertyDict) self.graph.push(node) def normalizeRelationships(self, nodes, relation): for node in nodes: for rel in node.match_incoming(relation): rel['norm_weight'] = rel['weight'] / node['in-weight'] self.graph.push(rel) def getNodes(self, feature): recordList = self.graph.cypher.execute( 'MATCH (node:%s) RETURN node' % feature) return [record.node for record in recordList] def getMatrix(self, nodesX, nodesY=None, relation='followed_by', propertyType='norm_weight'): if nodesY == None: nodesY = nodesX matrix = np.zeros([len(nodesX), len(nodesY)]) for node in nodesX: rowIndex = node['id'] for outRelation in node.match_outgoing(relation): colIndex = outRelation.end_node['id'] weight = outRelation[propertyType] matrix[rowIndex, colIndex] = weight return matrix def cypherContextSim(self): tx = self.graph.cypher.begin() tx.append(CONTEXT_SIM) tx.commit()
# | (c44901e:Person{born: 1960, name: "John Goodman"}), # | (b141775:Person{born: 1965, name: "John C. Reilly"}), # | (e40244b:Person{born: 1967, name: "Julia Roberts"})] # 六、通过节点/关系查找相关联的节点/关系 # 如果已经确定了一个节点或者关系,想找到和它相关的关系和节点,就可以使用match和match_one。 find_relationship = test_graph.match_one(start_node=find_code_1, end_node=find_code_2, bidirectional=False) print(find_relationship) # 如以上代码所示,match和match_one的参数包括start_node,Relationship,end_node中的至少一个。 # bidirectional参数的意义是指关系是否可以双向。 # 如果为False,则起始节点必须为start_node,结束节点必须为end_node。如果有Relationship参数,则一定按照Relationship对应的方向。 # 如果为True,则不需要关心方向问题,会把两个方向的数据都返回。 match_relation = test_graph.match(start_node=find_code_1, bidirectional=True) for i in match_relation: print(i) i['count'] += 1 test_graph.push(i) # 如以上代码所示,查找和find_code_1相关的关系。 # match里面的参数只写了start_node,bidirectional的值为True,则不会考虑方向问题,返回的是以find_code_1为起始节点和结束节点的所有关联关系。 # 如果,bidirectional的值为False,则只会返回以find_code_1为起始节点的所有关联关系。 # 七、关于节点和关系的建立 # 建立节点和关系之前最好先查找一下是否已经存在这个节点了。如果已经存在的话,则建立关系的时候使用自己查找到的这个节点,而不要新建,否则会出现一个新的节点。 # 如果一条条建立关系和节点的话,速度并不快。如果条件合适的话,最好还是用Neo4j的批量导入功能。 # 八、关于索引
class Diagnoser(): def __init__(self, description=None, symptoms=None, age=None, gender=None): self.description = description self.symptoms = symptoms self.age = age self.gender = gender self.symptomSet = self.getSymptomSet() # 获取所有可能的症状集合 self.graph = Graph("http://liublack.cn:7474", auth=("neo4j", "200001")) self.diseaseItemProerties = [ 'name', 'otherName', 'department', 'description', 'position', 'reason', 'symptom', 'examination', 'treatment', 'complication', 'prevention', 'care', 'typicalSymptom', 'relatedDisease' ] self.diseasesForMoreSymptoms = 3 jieba.set_dictionary(SYMPTOM_DIC_PATH) def diagnose(self, filteNum=None): # 第一步,根据病情描述获取症状列表 symptomList = self.getSymptoms() print('识别到的症状:', symptomList) # 第二步,根据症状列表获取所有相关的疾病 diseaseSet = self._getDiseaseFromSymptoms(symptomList) diseaseList = list(diseaseSet) print('可能的疾病:', diseaseList) # 第三步,计算所有疾病的置信度 scores = self._calDiseaseScore(diseaseList, symptomList) # 第四步,根据置信度得到预测疾病 diseaseList = list(zip(diseaseList, scores)) print('疾病的置信度为:', diseaseList) # 第五步,筛选出前filteNum个疾病,并查找相关症状 diseaseList.sort(key=lambda x: x[1], reverse=True) relatedSymptoms = self._getSymptomsFromDisease( diseaseList[0:self.diseasesForMoreSymptoms]) relatedSymptoms = list(relatedSymptoms - set(symptomList)) # 第六步,给出最终结果 if filteNum is not None: diseaseList = diseaseList[0:filteNum] diseaseDetials = self._getDiseaseDetails(diseaseList) # relatedSymptoms = self._getRelatedSymptoms(symptomList) result = {"disease": diseaseDetials, "symptoms": relatedSymptoms} result = json.dumps(result, ensure_ascii=False) print('最终结果:', result) return result def getSymptomSet(self): s = set() with open(SYMPTOM_DIC_PATH, 'r') as f: for line in f.readlines(): s.add(line.strip().split(' ')[0]) return s def getSymptoms(self): if self.symptoms is None: self.symptoms = [] else: map(lambda s: s.strip(), self.symptoms) self.symptoms.extend(self.processDesc()) return self.symptoms def processDesc(self): if self.description is None: return [] self.description = ''.join(self.description.split(' ')) symptoms = [] words = list(jieba.cut(self.description)) print('分词结果:', words) for word in words: if word in self.symptomSet: symptoms.append(word) return symptoms def _calDiseaseScore(self, diseaseList, symptomList): scores = [] # 首先计算每一种症状对应的疾病数目 scoreSymptom = [] for symptom in symptomList: scoreSymptom.append(len(self._getDiseaseFromSymptoms([symptom]))) # 接下来计算每种疾病的置信度 for disease in diseaseList: score = 0 for idx, symptom in enumerate(symptomList): if self._existHaveRelationship(disease, symptom): score += 1.0 / scoreSymptom[idx] scores.append(score) return scores def _getSymptomsFromDisease(self, diseaseList): symptomSet = set() for disease in diseaseList: node = self.graph.nodes.match('disease', name=disease).first() rels = self.graph.match((node, ), r_type='d-s') for r in rels: symptomSet.add(r.end_node['name']) return symptomSet def _getDiseaseFromSymptoms(self, symptomList): diseaseSet = set() for symptom in symptomList: node = self.graph.nodes.match('symptom', name=symptom).first() rels = self.graph.match((None, node), r_type='d-s') for r in rels: diseaseSet.add(r.start_node['name']) return diseaseSet def _existHaveRelationship(self, disease, symptom): ndisease = self.graph.nodes.match('disease', name=disease).first() nsymptom = self.graph.nodes.match('symptom', name=symptom).first() if ndisease is None or nsymptom is None: return False rel = self.graph.match_one((ndisease, nsymptom), r_type='d-s') return rel is not None def _getDiseaseDetails(self, diseaseList): details = [] for disease in diseaseList: node = self.graph.nodes.match('disease', name=disease).first() diseaseItem = dict() for pname in self.diseaseItemProerties: diseaseItem[pname] = node[pname] details.append(diseaseItem) return details def _getRelatedSymptoms(self, symptomList): symptoms = set() for symptom in symptomList: node = self.graph.nodes.match('symptom', name=symptom).first() rels = self.graph.match((node, None), r_type='s-s') relatedSymptoms = [rel.end_node['name'] for rel in rels] symptoms.update(relatedSymptoms) return list(symptoms)
# 连接neo4j数据库 graph = Graph("http://127.0.0.1:7474", username="******", password="******") starttime = datetime.datetime.now() node_label = "股票名称" node_name = "南方" relation_type = "持股" nodes = graph.nodes.match(node_label, name__contains=node_name) print(nodes) if len(nodes) == 0: print("没有找到这支股票呀,可能股票名称有误,换个名字试试?") elif len(nodes) == 1: node = nodes.first() relationships = graph.match((None, node), r_type=relation_type) stock_sum = 0 for relation in relationships: stock_sum += relation["股数"] print(relation) print(stock_sum) else: node_list = [] for node in nodes: node_list.append(node["name"]) print("包含这个股票名字的,有好几支呢", node_list, "您想了解哪一支呢") endtime = datetime.datetime.now() print(endtime - starttime)
class NeoRepo(): def __init__(self): self._host = "140.82.17.30" self.g = Graph("http://140.82.17.30", username="******", password="******") def add_user(self, user): n = Node("User", name=user) self.g.merge(n) def add_repo(self, repo): n = Node("Repo", name=repo) self.g.merge(n) def get_user(self, user): n = self.g.find_one("User", property_key='name', property_value=user) return n def get_repo(self, repo): n = self.g.find_one("Repo", property_key='name', property_value=repo) return n def add_rel(self, user, repo, rel_type): user = Node("User", name=user) repo = Node("Repo", name=repo) rel = Relationship(user, rel_type, repo) self.g.merge(rel) def match_user(self, user, rel_type='star'): if isinstance(user, str): user = self.get_user(user) if user is None: return [] match = self.g.match(start_node=user, bidirectional=False, rel_type=rel_type) return match def match_repo(self, repo, rel_type='star'): if isinstance(repo, str): repo = self.get_repo(repo) if repo is None: return [] match = self.g.match(end_node=repo, bidirectional=False, rel_type=rel_type) return match def match_one(self, user, repo, rel_type='star'): if isinstance(user, str): user = self.get_user(user) if isinstance(repo, str): repo = self.get_repo(repo) if user is None: return None if repo is None: return None match = self.g.match_one(start_node=user, end_node=repo, bidirectional=False, rel_type=rel_type) return match def suggest(self, repo): match_repo = self.match_repo(repo) count = {} for item_repo in match_repo: user = item_repo.start_node() # count[user['name']] = 0 match_user = self.match_user(user) for item_user in match_user: repo_suggest = item_user.end_node() if repo_suggest['name'] in count: count[repo_suggest['name']] += 1 else: count[repo_suggest['name']] = 1 if count == {}: return [] return (sorted(count.items(), key=lambda item: item[1], reverse=True))[1:51]
print marnee # Let's find Julian julian_node = graph.find_one("Person", property_key="name", property_value="Julian") print "find_one Julian %s" % julian_node # Let's find all the Persons Julian knows # show the Cypher -- MATCH # show the code # graph.match() # graph.match_one() julian_knows = graph.match(start_node=julian_node, rel_type="KNOWS", end_node=None) for friend in julian_knows: print "friend %s" % friend # looks like Julian has no friends. that is because the relationship goes the other way # show graph #who knows Julian knows_julian = graph.match(start_node=None, rel_type="KNOWS", end_node=julian_node) for friend_relationship in knows_julian: print "friend %s" % friend_relationship # this looks like Cypher -- how do I use this? knows_julian = graph.match(start_node=None,
def key_entity(): print "storing keywords" # Create the AlchemyAPI Object alchemyapi = AlchemyAPI() art_keywords = {} art_entities = {} count = 0 graph = Graph("http://*****:*****@localhost:7474/db/data/") article_query = """MATCH (n:article) Return distinct n.url as url""" result = graph.cypher.execute(article_query) keyword_count = 0 entity_count = 0 art_count = 0 for arti in result: if count >= 1000: print "Alchemy limit exceeds" exit() art = arti['url'] article_node = """ MATCH (article:article{url:'"""+art+"""'}) SET article.processed = 'yes' Return article; """ article = graph.cypher.execute(article_node) if art not in art_keywords.keys(): art_keywords[art] = [] response = alchemyapi.keywords('url', art, {'sentiment': 1}) count = count + 1 art_count = art_count + 1 if response['status'] == 'OK': for keyword in response['keywords']: # print('text: ', keyword['text'].encode('utf-8')) key = str(keyword['text'].encode('utf-8')).replace("'","") art_keywords[art].append(key) rel_dict = {} rel_dict['relevance'] = keyword['relevance'] rel_dict['sentiment'] = keyword['sentiment']['type'] if 'score' in keyword['sentiment']: rel_dict['sentiment_score'] = keyword['sentiment']['score'] keyword_node = """ MERGE (keyword:Keywords{text:'"""+key+"""'}) Return keyword; """ at_keywords = graph.cypher.execute(keyword_node) if len(list(graph.match(start_node=article.one,end_node=at_keywords.one, rel_type=("has_keyword",rel_dict)))) == 0: pth = Path(article.one,("has_keyword",rel_dict),at_keywords.one) graph.create(pth) keyword_count = keyword_count + 1 if count >= 1000: print "Alchemy limit exceeds" exit() if art not in art_entities.keys(): art_entities[art] = [] response = alchemyapi.entities('url', art, {'sentiment': 1}) count = count + 1 if response['status'] == 'OK': for entities in response['entities']: # print('text: ', entities['text'].encode('utf-8')) key = str(entities['text'].encode('utf-8')).replace("'","") art_entities[art].append(key) rel_dict = {} rel_dict['type'] = entities['type'] rel_dict['relevance'] = entities['relevance'] rel_dict['sentiment'] = entities['sentiment']['type'] if 'score' in entities['sentiment']: rel_dict['sentiment_score'] = entities['sentiment']['score'] entities_node = """ MERGE (entities:Entities{text:'"""+key+"""'}) Return entities; """ if len(list(graph.match(start_node=article.one,end_node=at_entities.one, rel_type=("has_entity",rel_dict)))) == 0: at_entities = graph.cypher.execute(entities_node) pth = Path(article.one,("has_entity",rel_dict),at_entities.one) graph.create(pth) entity_count = entity_count + 1 return {'articles':str(art_count),'keywords':str(keyword_count),'entities':str(entity_count)}
def leads(csvFilePath, config_file, act): config = ConfigParser.ConfigParser() config.read(config_file) nodes = config.options("nodes") relation = config.options("relation") # fetch from csv and store in graph print "Storing Leads" graph = Graph("http://*****:*****@localhost:7474/db/data/") csvfile = open(csvFilePath) reader = csv.DictReader(csvfile) reslt = {} indi_count = 0 for row in reader: try: nodeList={} for n in nodes: node_atr = config.get("nodes",n) attr = json.loads(node_atr) individual_node = "" try: if bool(attr): individual_node = """ MERGE ("""+act+""":"""+n+"""{""" for attr_key in attr.keys(): individual_node=individual_node+str(attr_key)+""" :'"""+(str(row[attr[attr_key]]).replace("'",""))+"""', """ individual_node = individual_node.strip(", ")+"""}) Return """+act+"""; """ individual = graph.cypher.execute(individual_node) nodeList[n]=individual indi_count=indi_count+1 except Exception,ee: pass for n in relation: rel_atr = config.get("relation",n) attr = json.loads(rel_atr) try: if bool(attr): start_node = attr['start_node'] end_node = attr['end_node'] attributes = attr['attributes'] rel_dict={} for u in attributes.keys(): rel_dict[u] = (str(row[attributes[u]]).replace("'","")) if len(list(graph.match(start_node=nodeList[start_node].one,end_node=nodeList[end_node].one, rel_type=(n,rel_dict)))) == 0: graph.create(Path(nodeList[start_node].one,(n,rel_dict),nodeList[end_node].one)) except Exception,ee: pass
class AgoraUser(object): def __init__(self, graph_db=None): self.name = None self.unique_id = None self.mission_statement = None self.email = None self.is_mentor = False self.is_tutor = False self.is_visible = True self.is_available_for_in_person = True # self._interests_list = None self.is_admin = False self.graph_db = Graph("http://localhost:7474/db/data/") def get_user(self): user_node = self.graph_db.find_one(AgoraLabel.USER, property_key='email', property_value=self.email) if not user_node is None: self.name = user_node["name"] self.unique_id = user_node["unique_id"] self.mission_statement = user_node["mission_statement"] self.email = user_node["email"] self.is_mentor = user_node["is_mentor"] self.is_tutor = user_node["is_tutor"] self.is_visible = user_node["is_visible"] self.is_available_for_in_person = user_node["is_available_for_in_person"] self.is_admin = user_node["is_admin"] def create_user(self): """ create a new user based on the attributes :return: node """ unique_id = str(uuid.uuid4()) new_user_properties = { "name": self.name, "mission_statement": self.mission_statement, "unique_id": unique_id, "email": self.email.lower(), "is_mentor": True, "is_tutor": True, "is_visible": True, "is_available_for_in_person": True, "is_admin": True} new_user_node = Node.cast(AgoraLabel.USER, new_user_properties) try: self.graph_db.create(new_user_node) except: pass return new_user_node @property def user_node(self): """ get a user neo4j.Node :return: neo4j.Node """ return self.graph_db.find_one(AgoraLabel.USER, property_key='email', property_value=self.email) # return self.graph_db.get_or_create_indexed_node(index_name=AgoraLabel.USER, # key='email', value=self.email) @property def user_interests(self): """ get user interests :return: list of interests """ user_interests = self.graph_db.match(start_node=self.user_node, rel_type=AgoraRelationship.INTERESTED_IN, end_node=None) #create a list of tuples of interests and the users's relationship to them interests_list = [] for item in user_interests: interests_list.append((item.end_node["name"], item["description"])) # return [item.end_node["name"] for item in user_interests] return interests_list @property def user_goals(self): """ get user interests :return: list of interests """ user_goals = self.graph_db.match(start_node=self.user_node, rel_type=AgoraRelationship.HAS_GOAL, end_node=None) #create a list of tuples of interests and the users's relationship to them goals_list = [] for item in user_goals: goals_list.append((item.end_node["title"], item["description"])) # return [item.end_node["name"] for item in user_interests] return goals_list @property def user_groups(self): """ :return: list of tuples of the groups """ user_groups = self.graph_db.match(start_node=self.user_node, rel_type=AgoraRelationship.STUDIES_WITH, end_node=None) #create a list of tuples of interests and the users's relationship to them groups_list = [] for item in user_groups: groups_list.append((item.end_node["name"], item["unique_id"])) # return [item.end_node["name"] for item in user_interests] return groups_list @property def user_orgs(self): """ :return: """ user_orgs = self.graph_db.match(start_node=self.user_node, rel_type=AgoraRelationship.MEMBER_OF, end_node=None) orgs_list = [] for item in user_orgs: orgs_list.append(item.end_node["name"]) return orgs_list def add_interest(self, interest_node): """ Add interest to user :param interest_node:py2neo Node :return: List of interests """ user_interest_relationship = Relationship(start_node=self.user_node, rel=AgoraRelationship.INTERESTED_IN, end_node=interest_node) self.graph_db.create_unique(user_interest_relationship) return self.user_interests def update_user(self): pass def make_admin(self): #new_user = self.graph_db.get_or_create_indexed_node(index_name=AgoraLabel.USER, key='email', value=self.email) self.user_node.add_labels(AgoraLabel.ADMIN) def add_goal(self, goal_node, goal_relationship_properties=None): """ Add goal to user :param goal_node: py2neo Node :return: List of user goals """ #get user node with unique id # user_node = self.graph_db.get_or_create_indexed_node(index_name=AgoraLabel.USER, # key='email', value=self.email) #create relationship between user and interest node user_goal_relationship = Relationship(start_node=self.user_node, rel=AgoraRelationship.HAS_GOAL, end_node=goal_node) self.graph_db.create_unique(user_goal_relationship) #TODO set properties on the relationship -- may use a unique id as the key return self.user_goals def add_group(self, group_node, group_relationship_properties=None): """ Add user as member of group :param group_node: py2neo Node :return: """ user_group_relationship = Relationship(start_node=self.user_node, rel=AgoraRelationship.MEMBER_OF, end_node=group_node) self.graph_db.create_unique(user_group_relationship) #TODO set properties on the relationsip # group_relationship_properties["unique_id"] = str(uuid.uuid4()) def add_organization(self, org_node): """ add user to organization :param org_node: py2neo Node :return: list of tuple of interests """ user_org_relationship = Relationship(start_node=self.user_node, rel=AgoraRelationship.MEMBER_OF, end_node=org_node) self.graph_db.create_unique(user_org_relationship)
class Access: def __init__(self, events): config = Conf() authenticate(config.db_host, config.db_username, config.db_password) self.graph = Graph() self.events = events def is_unique_entry(self, entry): result = self.graph.find_one('entry', 'clean_url', entry.clean_url) if result is None: node = Node('entry', clean_url=entry.clean_url, raw_url=entry.raw_url, context=entry.context, searched=0) self.graph.create(node) return True else: return result.properties['searched'] == 0 def mark_searched(self, entry): stmt = 'MATCH (found:entry {clean_url: {URL}, searched:0}) SET found.searched = 1' self.graph.cypher.execute_one(stmt, URL=entry.clean_url) def is_new_node(self, entry): if entry.next_entry is None: next_id = None else: next_id = entry.next_entry.id result = self.graph.find_one('node', 'self_id', entry.id) if result is None: self.events.on_creating_node() node = Node('node', clean_url=entry.clean_url, raw_url=entry.raw_url, context=entry.context, next_id=next_id, self_id=entry.id, created=entry.created, created_utc=entry.created_utc, source=entry.source_comment, html=entry.html_comment, title=entry.title, user=entry.user, submission_id=entry.submission_id) self.graph.create(node) return node, False else: self.events.on_node_exists() return result, True def get_parents(self, entry): stmt = 'MATCH (found:node {next_id: {ID}}) return found' results = self.graph.cypher.execute(stmt, ID=entry.id) return results.to_subgraph().nodes def add_link(self, parent, child): if len(list(self.graph.match(start_node=parent, end_node=child, rel_type='linksTo'))) > 0: return False rel = Relationship(parent, 'linksTo', child) self.graph.create_unique(rel) return True def get_terminus(self, limit=100): stmt = 'MATCH (a:node) WHERE NOT (a)-[:linksTo]->() and (not has(a.broken) or a.broken = false) ' + \ 'return a LIMIT {LIM}' results = self.graph.cypher.execute(stmt, LIM=limit) return results.to_subgraph().nodes def get_entry(self, size): if size > 0: stmt = 'MATCH (found:entry {searched:0}) RETURN found LIMIT {LIM}' results = self.graph.cypher.execute(stmt, LIM=size) else: stmt = 'MATCH (found:entry {searched:0}) RETURN found' results = self.graph.cypher.execute(stmt) return results.to_subgraph().nodes def get_starts(self): stmt = 'MATCH (a:node) WHERE NOT ()-[:linksTo]->(a) RETURN a' results = self.graph.cypher.execute(stmt) return results.to_subgraph().nodes def get_next_nodes(self, node): stmt = 'MATCH (a:node)-[:linksTo]->(b:node) WHERE id(a) = {ID} RETURN b' results = self.graph.cypher.execute(stmt, ID=node._id) return results.to_subgraph().nodes @staticmethod def set_terminus(node): node['broken'] = True node.push() @staticmethod def update_parent_next(parent, entry): parent['next_id'] = entry.id parent.push()
class AgoraGroup(object): def __init__(self, graph_db): self.name = None self.unique_id = None self.description = None self.is_open = None self.is_invite_only = None self.meeting_location = None self.next_meeting_date = None self.members = [] self.interests = [] self.group_leader_username = None self.graph_db = Graph() @property def group_node(self): """ get a group node based on the unique id attribute :return: neo4j.Node """ return self.graph_db.find_one(AgoraLabel.STUDYGROUP, property_key='unique_id', property_value=self.unique_id) @property def group_interests(self): """ get user interests :return: list of interests """ group_interests = self.graph_db.match(start_node=self.group_node, rel_type=AgoraRelationship.INTERESTED_IN, end_node=None) # create a list of tuples of interests and the users's relationship to them interests_list = [] for item in group_interests: interests_list.append((item.end_node["name"], item["description"])) # return [item.end_node["name"] for item in user_interests] return interests_list def create_group(self): """ create new study group or circle :return: py2neo Node """ self.unique_id = str(uuid.uuid4()) new_group_properties = { "name": self.name, "description": self.description, "unique_id": self.unique_id, "is_open": self.is_open, "is_invite_only": self.is_invite_only, "meeting_location": self.meeting_location, "next_meeting_date": self.next_meeting_date, } new_group_node = Node.cast(AgoraLabel.STUDYGROUP, new_group_properties) self.graph_db.create(new_group_node) return new_group_node def add_interest(self, interest_node): """ link interests to a study group :return: list of group interests """ group_interest_relationship = Relationship(start_node=interest_node, rel=AgoraRelationship.INTERESTED_IN, end_node=self.group_node) self.graph_db.create(group_interest_relationship) # TODO set properties on RELATIONSHIP return self.group_interests def update_group(self): pass def close_group(self): pass
class User(object): def __init__(self, graph_db=None): self.name = '' self.call_sign = '' self.first_name = '' self.last_name = '' self.id = '' self.mission_statement = '' self.about = '' self.email = '' self.is_mentor = False self.is_tutor = False self.is_visible = True self.is_available_for_in_person = True # self._interests_list = None # self.is_admin = False # self.password = '' # self.salt = '' # self.permanent_web_token = '' # self.temporary_web_token = '' self.join_date = None self.last_active_date = '' self._graph_db = Graph(settings.DATABASE_URL) @property def user_properties(self): """ setup user properties :return: dictionary of properties """ properties_dict = dict(self.__dict__) del properties_dict['_graph_db'] return properties_dict def set_user_properties(self, user_properties): """ :param user_properties: :return: """ for key, value in user_properties.iteritems(): setattr(self, key, value) def get_user(self): user_node = self.user_node if user_node is not None: user_properties = dict(user_node.properties) for key, value in user_properties.iteritems(): setattr(self, key, value) return True else: return False def create_user(self, user_properties=None): """ create a new user based on the attributes :return: node """ #TODO exception handling self.join_date = datetime.date.today() self.last_active_date = self.join_date self.id = str(uuid.uuid4()) if user_properties is not None: self.set_user_properties(user_properties) new_user_node = Node.cast(GraphLabel.USER, self.user_properties) try: self._graph_db.create(new_user_node) except: pass # print 'node probably found. see message' # print sys.exc_info() return new_user_node @property def user_node(self): """ get a user Node :return: py2neo Node """ if self.email != '': return self._graph_db.find_one(GraphLabel.USER, property_key='email', property_value=self.email) elif self.id != '': return self._graph_db.find_one(GraphLabel.USER, property_key='id', property_value=self.id) # return self.graph_db.get_or_create_indexed_node(index_name=GraphLabel.USER, # key='email', value=self.email) @property def user_interests(self): """ get user interests :return: dictionary of interests """ user_interests = self._graph_db.match(start_node=self.user_node, rel_type=GraphRelationship.INTERESTED_IN, end_node=None) #create a list of tuples of interests and the users's relationship to them interests_list = [] for rel in user_interests: interest_dict = dict(rel.end_node.properties, **rel.properties) interests_list.append(dict(rel.end_node.properties)) return interests_list @property def user_goals(self): """ get user interests :return: list of interests """ #TODO do not need a list of interests -- HATEOAS -- MMD 3/8/2015 user_goals = self._graph_db.match(start_node=self.user_node, rel_type=GraphRelationship.HAS_GOAL, end_node=None) goals_list = [] goal_interests_list = [] for rel in user_goals: goal_properties = dict(rel.end_node.properties) goal = Goal() goal.id = goal_properties['id'] interests = goal.goal_interests interests_list = [] for interest in interests: interests_list.append(interest['name']) goal_properties['interests'] = interests_list goals_list.append(goal_properties) return goals_list @property def user_groups(self): """ :return: list of tuples of the groups """ #TODO add list of related interests user_groups = self._graph_db.match(start_node=self.user_node, rel_type=GraphRelationship.STUDIES_WITH, end_node=None) # create a list of tuples of interests and the users's relationship to them groups_list = [] for rel in user_groups: group_properties = dict(rel.end_node.properties) group = Group() group.id = group_properties['id'] interests = group.group_interests group_interests_list = [] for interest in interests: group_interests_list.append(interest['name']) group_properties['interests'] = group_interests_list groups_list.append(group_properties) return groups_list @property def user_orgs(self): """ :return: """ user_orgs = self._graph_db.match(start_node=self.user_node, rel_type=GraphRelationship.MEMBER_OF, end_node=None) orgs_list = [] for rel in user_orgs: org_properties = dict(rel.end_node.properties) org = Organization() org.id = org_properties['id'] interests = org.org_interests interests_list = [] for interest in interests: interests_list.append(interest['name']) org_properties['interests'] = interests_list orgs_list.append(org_properties) return orgs_list @property def user_locations(self): """ :return: """ user_locations = self._graph_db.match(start_node=self.user_node, rel_type=GraphRelationship.LOCATED_IN, end_node=None) locations_list = [] for rel in user_locations: locations_list.append(rel.end_node.properties) return locations_list def get_local_users_shared_interests_near_location(self): #, location_node): """ get a dictionary of user with shared interests with this user :param : :return: dictionary of {interests: [users]} """ # users_shared_interests params = { 'email': '*****@*****.**' } cypher_str = "MATCH (u:USER {email:{email}})-[url:LOCATED_IN]->(l:LOCATION)" cypher_str += "<-[orl:LOCATED_IN]-(o:USER) " cypher_str += "WITH u, o, l, url, orl " cypher_str += "MATCH (u)-[ru:INTERESTED_IN]->" cypher_str += "(i:INTEREST)<-[ro:INTERESTED_IN]-(o) " cypher_str += "RETURN i.name as interest_name, i.id as interest_id, " \ "o.name as user_name, o.id as user_id" #, u, ru, ro, l, url, orl" # print cypher_str results = Graph().cypher.execute(cypher_str, params) # self.graph_db.cypher.stream(cypher_str) # self.graph_db.cypher.execute(cypher_str) interest_users_dict = {} print results for item in results: interest = item['interest_name'] user = item['user_name'] if interest_users_dict.has_key(interest): interest_users_dict[interest].append(user) else: interest_users_dict[interest] = [] interest_users_dict[interest].append(user) # user = item['user_name'] # cur_users_list.append(interest_users_dict.get(interest)) # if interest_users_dict.has_key(interest): # # if interest in interest_users_dict.keys(): # cur_users_list = interest_users_dict[interest] # # cur_users_list = interest_users_dict.get(interest) # else: # interest_users_dict[interest] = [] # cur_users_list.append(user) # interest_users_dict[interest] = cur_users_list # interest_users_dict[interest] = interest_users_dict.get(interest) # user_details = (user_node['name'], user_node['email'], user_node['id']) # user_list.append(user_details) return interest_users_dict def add_interest(self, interest_id, experience_properties_dict=None): """ Add interest to user :param interest id:string uuid :return: List of interests """ #TODO add exception handling interest = Interest() interest.id = interest_id interest_node = interest.interest_node_by_id user_interest_relationship = Relationship(self.user_node, GraphRelationship.INTERESTED_IN, interest_node) for key, value in experience_properties_dict.iteritems(): user_interest_relationship[key] = value try: self._graph_db.create_unique(user_interest_relationship) except: pass return self.user_interests def update_interest(self, interest_id, experience_properties_dict): interest = Interest() interest.id = interest_id interest_node = interest.interest_node_by_id user_interest_relationship = self._graph_db.match_one(start_node=self.user_node, rel_type=GraphRelationship.INTERESTED_IN, end_node=interest_node) for key, value in experience_properties_dict.iteritems(): user_interest_relationship.properties[key] = value user_interest_relationship.push() def delete_interest(self, interest_id): """ drop interest relationship from user given the interest_id :param interest_id: str(uuid.uuid4()) :return: """ #TODO exception handling interest = Interest() interest.id = interest_id interest_node = interest.interest_node_by_id user_interest_relationship = self._graph_db.match_one(start_node=self.user_node, rel_type=GraphRelationship.INTERESTED_IN, end_node=interest_node) self._graph_db.delete(user_interest_relationship) def update_user(self): user_node = self.user_node user_properties = dict(self.user_properties) for key, value in user_properties.iteritems(): user_node[key] = value # user_properties[key] user_node.push() # def make_admin(self): # #new_user = self.graph_db.get_or_create_indexed_node(index_name=GraphLabel.USER, key='email', value=self.email) # self.user_node.add_labels(GraphLabel.ADMIN) def add_goal(self, goal_properties): """ Add goal to user :param goal_id: string uuid :return: List of user goals """ #TODO exception handling goal = Goal() goal.set_goal_properties(goal_properties=goal_properties) goal.create_goal() # create relationship between user and interest node user_goal_relationship = Relationship(self.user_node, GraphRelationship.HAS_GOAL, goal.goal_node) self._graph_db.create_unique(user_goal_relationship) #TODO set properties on the relationship -- may use a unique id as the key return self.user_goals def delete_goal(self, goal_id): user_node = self.user_node goal = Goal() goal.id = goal_id # have to remove all relationships before deleteing a node goal.delete_all_interests() goal_node = goal.goal_node user_goal_rel = self._graph_db.match_one(start_node=user_node, rel_type=GraphRelationship.HAS_GOAL, end_node=goal_node) self._graph_db.delete(user_goal_rel) self._graph_db.delete(goal_node) def join_group(self, group_id, group_relationship_properties=None): """ Add user as member of group :param group_id: string uuid :return: """ #TODO exception handling group = Group() group.id = group_id # relationship properties join_properties = { 'join_date': datetime.date.today() } user_group_relationship = Relationship(self.user_node, GraphRelationship.STUDIES_WITH, group.group_node) # properties=join_properties) for key, value in join_properties.iteritems(): user_group_relationship[key] = value try: self._graph_db.create_unique(user_group_relationship) except: pass #TODO set properties on the relationsip # group_relationship_properties["id"] = str(uuid.uuid4()) def leave_group(self, group_id): """ remove relationship between user and study group :param group_id: string uuid :return: None """ #TODO exception handling group = Group() group.id = group_id user_group_relationship = self._graph_db.match_one(start_node=self.user_node, rel_type=GraphRelationship.MEMBER_OF, end_node=group.group_node) self._graph_db.delete(user_group_relationship) def delete_group(self, group_id): pass def join_organization(self, organization_id): """ add user to organization :param organization_id: string uuid :return: list of tuple of interests """ #TODO exception handling org = Organization() org.id = organization_id user_org_relationship = Relationship(self.user_node, GraphRelationship.MEMBER_OF, org.org_node) try: self._graph_db.create_unique(user_org_relationship) except: print sys.exc_info()[0] def leave_organization(self, organization_id): """ remove relationship between user and organization :param organization_id: :return: """ #TODO exception handling org = Organization() org.id = organization_id user_org_relationship = self._graph_db.match_one(start_node=self.user_node, rel_type=GraphRelationship.MEMBER_OF, end_node=org.org_node) self._graph_db.delete(user_org_relationship) def add_location(self, location_json): """ link user to location nodes :param locations_place_id: :return: """ #TODO exception handling #TODO do in location and pass in the node from the actual object (better pattern) location_place_id = location_json['id'] location = Location() location.id = location_place_id location_node = location.location_node_by_place_id if not location_node: location.set_location_properties(location_json) location.create_location() location_node = location.location_node_by_place_id() user_location_relationship = Relationship(self.user_node, GraphRelationship.LOCATED_IN, location_node) # try: self._graph_db.create_unique(user_location_relationship) # except: # pass def create_cq(self, cq_dict, cq_interests_dict=None): Cq.create_cq(user_node=self.user_node, cq_dict=cq_dict) def create_converation_between_users(self, user_id_started, user_id_with, conversation_properties): # self.id = uuid.uuid4() conversation_properties['id'] = str(uuid.uuid4()) new_convo_node = Node.cast(GraphLabel.CONVERSATION, conversation_properties) try: convo_node, = self._graph_db.create(new_convo_node) # create new conversation node user_started = User() user_started.id = user_id_started user_with = User() user_with.id = user_id_with # create started conversation relationship user_started_relationship = Relationship(user_started.user_node, GraphRelationship.STARTED, convo_node) self._graph_db.create(user_started_relationship) # create started conversation with relationship convo_with_relationship = Relationship(convo_node, GraphRelationship.WITH, user_with.user_node) self._graph_db.create(convo_with_relationship) return convo_node.properties['id'] except: pass #TODO add exception handling # @staticmethod def matched_users(self, match_string, limit): """ :param match_string: :param limit: :return: dictionary of search results """ params = { 'match': '(?i)%s.*' % match_string, 'limit': limit } cypher_str = "MATCH (user:USER ) " \ "WHERE user.name =~ {match} " \ "RETURN user.name as name, user.id as id " \ "LIMIT {limit}" match_results = self._graph_db.cypher.execute(statement=cypher_str, parameters=params) root = {} root['count'] = 0 user_found = {} users_list = [] for item in match_results: user_found['id'] = item.id user_found['name'] = item.name # self.id = item['id'] # self.get_user() # users_list.append(dict(self.user_properties)) users_list.append(dict(user_found)) root['count'] += 1 root['users'] = users_list return root def register_user(self, email): verification_email = notifications.Notifications() verification_email.recipients = [email] s = URLSafeTimedSerializer(secret_key=settings.TOKEN_SECRET_KEY) payload = s.dumps(email) verification_email.subject = settings.ACTIVATION_SUBJECT verification_email.message = settings.ACTIVATION_MESSAGE verification_email.url = self.construct_verification_url(payload=payload) verification_email.send_by_gmail() def activate_user(self, payload, email): s = URLSafeTimedSerializer(secret_key=settings.TOKEN_SECRET_KEY) payload_email = s.loads(payload, max_age=settings.TOKEN_EXPIRES_IN) # 10 minutes if email == payload_email: self.email = email self.get_user() self.permanent_web_token = self.create_web_token() if self.id == '': self.create_user() else: self.update_user() else: raise BadSignature('bad email') def update_last_active_date(self): self.last_active_date = datetime.date.today() user_node = self.user_node user_node['last_active_date'] = self.last_active_date user_node.push() def construct_verification_url(self, payload): return settings.SITE_URL + settings.ACTIVATION_ROUTE + "/%s" % payload def create_web_token(self): s = URLSafeSerializer(secret_key=settings.TOKEN_SECRET_KEY) return s.dumps(self.id) def user_relationships_for_json(self, auth_id): root = self.user_profile_for_json() root['__class'] = self.__class__.__name__ root['interests'] = self.user_interests root['locations'] = self.user_locations root['goals'] = self.user_goals root['groups'] = self.user_groups root['organizations'] = self.user_orgs root['is_owner'] = (auth_id == self.id) root['allow_edit'] = (auth_id == self.id) root['allow_message'] = (auth_id is not None) return root def user_profile_for_json(self): root = self.user_properties return root def user_interests_for_json(self): root = {} root['__class'] = self.__class__.__name__ root['id'] = self.id root['email'] = self.email root['interests'] = self.user_interests return root def user_goals_for_json(self): root = {} root['__class'] = self.__class__.__name__ root['id'] = self.id root['email'] = self.email root['goals'] = self.user_goals # root['interests'] = self.user_goals['interests'] return root def user_groups_for_json(self): root = {} root['__class'] = self.__class__.__name__ root['id'] = self.id root['email'] = self.email root['groups'] = self.user_groups return root def user_locations_for_json(self, auth_id): root = {} root['__class'] = self.__class__.__name__ root['id'] = self.id if self.id == auth_id: root ['allow_edit'] = True return root def local_users_with_shared_interests_for_json(self): root = {} root['__class'] = self.__class__.__name__ root['id'] = self.id root['email'] = self.email root['users'] = self.get_local_users_shared_interests_near_location() return root def activated_user_for_json(self): root = {} root['__class'] = self.__class__.__name__ root['x_auth_key'] = self.permanent_web_token return root
class GraphExporter: def __init__(self): authenticate(neo4j.HOST_PORT, neo4j.USERNAME, neo4j.PASSWORD) self.neo4j_db = Graph(neo4j.REMOTE_URI) def create_taikonetwork_graph(self): print("> Taiko Network Graph: querying all nodes and relationships...") self.graph = nx.Graph() self._add_group_nodes() self._add_memberships() self._add_member_nodes() self._add_unique_connections() print("> Taiko Network Graph: SUCCESSFULLY CREATED!\n" "> Export to graph file format to save.\n") def create_demographic_graph(self): print("> Demographic Graph: querying all Member nodes and Connection rels...") self.graph = nx.Graph() self._add_member_nodes(demo=True) self._add_unique_connections(demo=True) print("> Demographic Graph: SUCCESSFULLY CREATED!\n" "> Export to graph file format to save.\n") def export_gexf_graph(self, filepath='graph.gexf'): nx.write_gexf(self.graph, filepath, encoding='utf-8', prettyprint=True, version='1.2draft') def _add_group_nodes(self): groups = self.neo4j_db.find('Group') color = {'r': 255, 'g': 2, 'b': 97, 'a': 1} for g in groups: data = g.properties self.graph.add_node( g._id, label=data['name'], sf_id=data['sf_id'], viz={'color': color}) def _add_member_nodes(self, demo=False): members = self.neo4j_db.find('Member') for m in members: data = m.properties color = self._random_color(m._id, 1) if demo: self.graph.add_node( m._id, label=data['firstname'] + ' ' + data['lastname'], gender=data['gender'], dob=data['dob'], race=data['race'], ethnicity=data['asian_ethnicity'], viz={'color': color}) else: self.graph.add_node( m._id, label=data['firstname'] + ' ' + data['lastname'], sf_id=data['sf_id'], viz={'color': color}) def _add_unique_connections(self, demo=False): connections = self.neo4j_db.match(rel_type='CONNECTED_TO') unique_rels = [] for c in connections: start = c.start_node._id end = c.end_node._id if (start, end) not in unique_rels and (end, start) not in unique_rels: if demo: color = {'r': 213, 'g': 213, 'b': 213, 'a': 0.3} else: color = self._random_color(start, 0.3) self.graph.add_edge(start, end, viz={'color': color}) unique_rels.append((start, end)) def _add_memberships(self): memberships = self.neo4j_db.match(rel_type='MEMBER_OF') for ms in memberships: color = self._random_color(ms.start_node._id, 0.3) self.graph.add_edge(ms.start_node._id, ms.end_node._id, viz={'color': color}) def _random_color(self, obj_id, alpha): colors = [{'r': 164, 'g': 243, 'b': 121}, {'r': 243, 'g': 230, 'b': 121}, {'r': 243, 'g': 121, 'b': 184}, {'r': 154, 'g': 121, 'b': 243}, {'r': 202, 'g': 243, 'b': 121}, {'r': 243, 'g': 177, 'b': 121}, {'r': 243, 'g': 121, 'b': 238}, {'r': 121, 'g': 243, 'b': 212}, {'r': 243, 'g': 190, 'b': 121}, {'r': 121, 'g': 194, 'b': 243}, {'r': 157, 'g': 2, 'b': 253}, {'r': 2, 'g': 86, 'b': 253}] c = colors[obj_id % 12] c['a'] = alpha return c
def main(): # Defaults protocol = "http" hostName = "localhost" portNumber = 7474 dbPath = "/db/data/" userId = "" password = "" limit = 0 # limit = 0 means no limit, limit =n where n > 0 limits queries to at most n rows csvpath = "." nodeLabels = "" batchsize = 1000 try: opts, args = getopt.getopt(sys.argv[1:], "?", ["help", "protocol=", "host=", "port=", "db=", "userid=", "password="******"limit=", "csvpath=", "nodelabels="]) except getopt.GetoptError: print "ERROR unknown option!" print "" usage() sys.exit(2) for opt, arg in opts: if opt in ('-?', '--help'): usage() sys.exit(0) elif opt == "--protocol": protocol = arg elif opt == "--host": hostName = arg elif opt == "--port": portNumber = arg elif opt == "--db": dbPath = arg elif opt == "--userid": userId = arg elif opt == "--password": password = arg elif opt == "--limit": limit = arg elif opt == "--csvpath": csvpath = arg elif opt == "--nodelabels": nodeLabels = arg else: print "ERROR: Unknown option", opt print "" usage() sys.exit(2) host = hostName + ":" + str(portNumber) url = protocol + "://" + host + dbPath print "Connect to", url if len(userId) > 0: authenticate(host, userId, password) graph = Graph(url) print "Connected:", graph.bound # Check if output directory exists if not os.path.isdir(csvpath): print "ERROR Directory doesn't exist", csvpath sys.exit(1) relationshipTables = {} # one table for each of the relationship types for the current label if len(nodeLabels) > 0: labels = nodeLabels.split(',') else: labels = graph.node_labels # Get list of labels from the database for label in labels: print "Get nodes for label:", label currentTable = table() nodecount=0 while True: matchLimit = batchsize if limit > 0: if nodecount < limit: if nodecount + batchsize > limit: matchLimit = limit - nodecount else: break nodeCountCheck = nodecount # nodes = graph.find(label) nodes = graph.cypher.stream("MATCH (n:" + str(label) + ") RETURN n ORDER BY id(n) SKIP {skip} LIMIT {limit}", {"skip": nodecount, "limit": matchLimit}) if not nodes: break for g_node in nodes: nodecount += 1 node = g_node.n row = node.properties.copy() row["nodeId"] = node._id currentTable.addRow(row) # get relationships if limit > 0: # limit is for n relationships per node, so you may end up with n^2 relationships! nodeRelationships = graph.match(start_node=node, limit=limit) else: nodeRelationships = graph.match(start_node=node) for rel in nodeRelationships: relTableName = str(label + "_" + rel.type) if relTableName in relationshipTables: relTable = relationshipTables[relTableName] else: relTable = table() relationshipTables[relTableName] = relTable relRows = rel.properties.copy() relRows["nodeId"] = node._id relRows["otherNodeId"] = rel.end_node._id relTable.addRow(relRows) print "\tNode count", nodecount, " at ", datetime.datetime.now() if nodecount == nodeCountCheck: print "No more nodes" break tableCsvFileName = label + ".csv" print "Export label CSV", tableCsvFileName currentTable.saveCsv(csvpath, tableCsvFileName) for relTableName in relationshipTables: relTable = relationshipTables[relTableName] relTableCsvFileName = relTableName + ".csv" print "Export relationship CSV", relTableCsvFileName relTable.saveCsv(csvpath, relTableCsvFileName) print "Finished"
class AgoraGoal(object): def __init__(self, graph_db): self.title = None self.unique_id = None self.description = None self.start_date = None self.end_date = None self.interests = [] self.achievements = [] self.graph_db = Graph() @property def goal_node(self): """ get a single goal node based on the attributes of the goal :return: neo4j.Node """ goal_node = self.graph_db.find_one(AgoraLabel.GOAL, property_key='unique_id', property_value=self.unique_id) return goal_node @property def goal_interests(self): goal_interests = self.graph_db.match(start_node=self.goal_node, rel_type=AgoraRelationship.GOAL_INTEREST, end_node=None) goal_interests_list = [] for item in goal_interests: goal_interests_list.append((item["name"], item["description"])) return goal_interests_list def create_goal(self): """ create a goal and relate to user :return: neo4j.Node """ # goal_node = self.get_goal() #TO GO get goal to prevent duplication? maybe not needed -- MMMD 11/12/2014 # if goal_node is None: self.unique_id = str(uuid.uuid4()) new_goal_properties = { "title": self.title, "description": self.description, "unique_id": self.unique_id, "start_date": self.start_date, "end_date": self.end_date} new_goal = Node.cast(AgoraLabel.GOAL, new_goal_properties) return new_goal def update_goal(self): """ update goal related to user :return: """ pass def link_goal_to_achievement(self): pass def add_interest(self, interest_node): goal_interest_relationship = Relationship(start_node=self.goal_node, rel=AgoraRelationship.GOAL_INTEREST, end_node=interest_node) self.graph_db.create_unique(goal_interest_relationship) return def get_goal(self): pass def delete_goal(self): pass
test_graph.create(node_2_call_node_1) # 节点/关系的属性赋值以及属性值的更新 node_1_call_node_2['count'] += 1 test_graph.push(node_1_call_node_2) # 通过属性值来查找节点和关系(find,find_one) find_code_1 = test_graph.find_one(label="Person", property_key="name", property_value="test_node_1") find_code_3 = test_graph.find_one(label="Person", property_key="name", property_value="test_node_2") print(find_code_1['name']) # 通过节点/关系查找相关联的节点/关系 find_relationship = test_graph.match_one(start_node=find_code_1, end_node=find_code_3, bidirectional=False) print(find_relationship) # match和match_one的参数包括start_node,Relationship,end_node中的至少一个。 match_relation = test_graph.match(start_node=find_code_1, bidirectional=True) for i in match_relation: print(i) i['count'] += 1 test_graph.push(i)
graph.cypher.execute(query, { 'profile': prof, 'favorite': fav } ) dennis = graph.find_one("soundcloud", "name", "Dennis") emma = graph.find_one("soundcloud", "name", "Emma") print dennis.properties, emma.properties #graph.create(alice) #graph.create(bob) #graph.create(chelsea) #bob, likes = graph.create({"name": "Bob"}, (alice, "likes", 0)) #chelsea, likes = graph.create({"name": "Chelsea"}, (alice, "likes", 0)) alice_likes_bob = Relationship(alice, "likes", bob, songs=["goodsong", "nicetune"]) alice_likes_chelsea = Relationship(alice, "likes", chelsea, songs = ['greatsong']) graph.create_unique(alice_likes_bob) graph.create_unique(alice_likes_chelsea) alice_likes_chelsea['songs'] += ['awesometrack'] print alice_likes_chelsea.properties for rel in graph.match(start_node=alice, rel_type="likes"): print rel.end_node["name"] print rel.properties
tx.create(parlamentar) tx.commit() print(f'Criou o no para o parlamentar {cota["txNomeParlamentar"]}') empresa = graph.nodes.match("Doador", cnpj=cota['txtCNPJCPF']).first() if not empresa: tx = graph.begin() empresa = Node("Doador", nome=cota['txtFornecedor'], cnpj=cota['txtCNPJCPF']) tx.create(empresa) tx.commit() print(f'Criou o no para a empresa {cota["txtFornecedor"]}') rel_cota = graph.match(nodes=(parlamentar, empresa), r_type="COTA").first() if not rel_cota: tx = graph.begin() rel_cota = Relationship(parlamentar, "COTA", empresa, valor=float(cota['vlrLiquido'])) tx.create(rel_cota) tx.commit() print(f'Criou a relacao de cota entre \ {cota["txNomeParlamentar"]} e {cota["txtFornecedor"]}') else: rel_cota['valor'] += float(cota['vlrLiquido']) graph.push(rel_cota) print(f'Atualizou a relacao de cota entre \
class NeoManager: def __init__(self, host, port, username, password): self.username = username self.host = host self.port = port self.password = password def connect(self): print("http://" + self.host + ":" + str(self.port), self.username, self.password) self.graph = Graph("http://" + self.host + ":" + str(self.port), username = self.username, password = self.password) if self.graph != None: print("Neo4j Database Connected.") self.selector = NodeSelector(self.graph) def createNode(self, nodelabel, nodename): nodename = str(nodename) nodelabel = str(nodelabel) node = Node(nodelabel, name = nodename) self.graph.create(node) return node def createRelation(self, nodeSrc, nodeDst, relationName): relationName = str(relationName) if nodeSrc == None or nodeDst == None: return relationship = Relationship(nodeSrc, relationName, nodeDst) print(relationship) # self.setRelationAttribute(relation, 'credential', 0.9) self.graph.create(relationship) return relationship def setRelationAttribute(self, relationship, attribute, val): relationship[attribute] = val return relationship[attribute] def getRelationAttribute(self, relationship, attribute): return relationship[attribute] def findByName(self, findName): findName = str(findName) trustable = self.graph.find_one(property_key = "name", property_value = findName, label = 'labelHolder') if trustable == None: untrustable = self.graph.find_one(property_key = "name", property_value = findName, label = 'Creditless') return False, untrustable else: return True, trustable def findAllByLabel(self, findLabel): findLabel = str(findLabel) selected = self.selector.select(findLabel) print(selected) def findNodeRelation(self, node): return self.graph.match_one(start_node = node, bidirectional = True) def hasStartToRelation(self, node, relstr): return self.graph.match(start_node=node, rel_type=relstr) def hasEndWithRelation(self, node, relstr): return self.graph.match(end_node=node, rel_type=relstr) def getRelationBetween(self, nodeA, nodeB): if nodeA == None or nodeB == None: return None else: return self.graph.match(start_node = nodeA, end_node = nodeB, bidirectional = True) # neo = NeoManager('localhost', 7474, 'neo4j', '123') # neo.connect() # with open('../Datasets/TrainSetUnique.csv', 'r', encoding = 'utf-8') as input: # reader = csv.reader(input) # # row: [0] entity1 [1] entity2 [2] relation [3] example # for row in reader: # node0 = neo.findByName(row[0]) # node1 = neo.findByName(row[1]) # print(node0) # if node0 == None: # node0 = neo.createNode("labelHolder", row[0]) # if node1 == None: # node1 = neo.createNode("labelHolder", row[1]) # relation = neo.getRelationBetween(node0, node1) # print(relation) # if relation == None or relation != row[2]: # print(row[2]) # relation = neo.createRelation(node0, node1, row[2])
from py2neo import Node, Relationship, Graph, NodeMatcher, RelationshipMatcher, walk graph = Graph('http://localhost:7474', username='******', password='******') ''' for node in graph.nodes: print(node) ''' n = graph.nodes.match('label') for i in n: print(i) ''' rps=graph.relationships.match('to') for r in rps: print(r) ''' relationship = graph.match(r_type='to') print(relationship, type(relationship)) #print(rps.graph.nodenum.)
class DBConc(object): def __init__(self): self.graph = Graph("http://liublack.cn:7474", auth=("neo4j", "200001")) def search_one(self, label, name): node = self.graph.nodes.match(label, name=name).first() if label == 'disease': return Disease(Node) elif label == 'symptom': return Symptom(node) return None def search(self, label, **keys): pass def exist(self, label, name): node = self.graph.nodes.match(label, name=name).first() return node is not None def insertDisease(self, disease): if self.exist('disease', disease['name']): return if type(disease) != Disease: raise Exception('type(disease) not equals Disease') diseaseNode = Node('disease', **disease.data) self.graph.create(diseaseNode) def insertSymptom(self, symptom): if self.exist('symptom', symptom['name']): return if type(symptom) != Symptom: raise Exception('type(symptom) not equals Symptom') symptomNode = Node('symptom', **symptom.data) self.graph.create(symptomNode) def deleteRelationships(self, rtype): try: subG = Subgraph(relationships=self.graph.relationships.match( r_type=rtype)) # self.graph.create(subG) self.graph.separate(subG) except ValueError as e: print(e) def establishRelationship(self, left, right, rtype, pname, correlation=None): self.deleteRelationships(rtype) nodes = self.graph.nodes.match(left) for lnode in nodes: print(type(lnode)) names = lnode[pname] for name in names: rnode = self.graph.nodes.match(right, name=name).first() if rnode is None: continue if self.graph.match_one((lnode, rnode), r_type=rtype) is None: if correlation is not None: # 计算相关性 try: value = correlation.similarity( lnode['name'], rnode['name']) value = (value + 1) / 2 except KeyError as e: print(e) value = 1 else: value = 1 r = Relationship(lnode, rtype, rnode, value=value) self.graph.create(r) def establishAllRelationship(self, correlation=None): self.establishRelationship('disease', 'disease', 'd-d', 'relatedDiseases', correlation=correlation) self.establishRelationship('disease', 'symptom', 'd-s', 'typicalSymptoms', correlation=correlation) self.establishRelationship('symptom', 'symptom', 's-s', 'relatedSymptoms', correlation=correlation) def getDSCorrelation(self, label='correlate', alpha=0.3, maxDepth=5, wvmodel=None): symptomSet = set() diseaseSet = set() result = {} with open(Configurer.SYMPTOM_DICT_PATH, 'r') as f: for line in f.readlines(): symptomSet.add(line.split(' ')[0]) logging.info('症状集加载完毕') with open(Configurer.DISEASE_DICT_PATH, 'r') as f: for line in f.readlines(): diseaseSet.add(line.split(' ')[0]) logging.info('疾病集合加载完毕') f = open(Configurer.DS_CORRELATION_PATH, 'w') for disease in diseaseSet: result[disease] = {} for symptom in symptomSet: result[disease][symptom] = '' try: statement = 'match (p1:disease {name: "%s"}), (p2:symptom {name:"%s"}), p = shortestpath((p1)-[*..%d]-(p2)) return p' % ( disease, symptom, maxDepth) cursor = self.graph.run(statement) path = cursor.current['p'] if cursor.forward() else None except Exception as e: path = None if path: value, frac, n = (0, 0, 0) for entity in walk(path): if isinstance(entity, Relationship): value += entity['value'] frac += (1 + alpha)**n n += 1 value /= frac result[disease][symptom] = (value, 'shortest path') elif wvmodel: try: value = wvmodel.similarity(disease, symptom) value = (value + 1) / 4 result[disease][symptom] = (value, 'w2vModel') except KeyError as e: logging.warning(str(e)) if result[disease][symptom] == '': value = 0.1 result[disease][symptom] = (0.1, 'cannot compute') logging.info('%s - %s - %s by %s\n' % (disease, result[disease][symptom][0], symptom, result[disease][symptom][1])) f.write(str(result[disease]) + '\n') f.flush() # f = open(Configurer.DS_CORRELATION_PATH, 'w') f.write('\n\n\n\n' + str(result)) return result def clearDB(self): self.graph.delete_all() def getSymptomsFromDisease(self, diseaseList): symptomSet = set() for disease in diseaseList: node = self.graph.nodes.match('disease', name=disease).first() rels = self.graph.match((node, ), r_type='have') for r in rels: symptomSet.add(r.end_node['name']) return symptomSet def getDiseaseFromSymptoms(self, symptomList): diseaseSet = set() for symptom in symptomList: node = self.graph.nodes.match('symptom', name=symptom).first() rels = self.graph.match((None, node), r_type='have') for r in rels: diseaseSet.add(r.start_node['name']) return diseaseSet def existHaveRelationship(self, disease, symptom): ndisease = self.graph.nodes.match('disease', name=disease).first() nsymptom = self.graph.nodes.match('symptom', name=symptom).first() if ndisease is None or nsymptom is None: return False rel = self.graph.match_one((ndisease, nsymptom), r_type='have') return rel is not None def getDiseaseDetails(self, diseaseList): details = [] for disease in diseaseList: node = self.graph.nodes.match('disease', name=disease).first() diseaseItem = dict() for pname in self.diseaseItemProerties: diseaseItem[pname] = node[pname] details.append(diseaseItem) return details def getRelatedSymptoms(self, symptomList): symptoms = set() for symptom in symptomList: node = self.graph.nodes.match('symptom', name=symptom).first() rels = self.graph.match((node, None), r_type='relate') relatedSymptoms = [rel.end_node['name'] for rel in rels] symptoms.update(relatedSymptoms) return list(symptoms)
class Neo4j(object): def __init__(self): self.graph = Graph(Config.NEO_URL, username=Config.NEO_USR, password=Config.NEO_PSW) self.mm = MongoManager.DBManager() def add_relation(self, node_name1, node_name2, movie_name='name', url='url'): """ 图中添加新的导演关系 若关系中的两个节点不在图中则自动创建 同时为关系添加电影名、发行时间、关系计数这几个参数 :param node_name1: :param node_name2: :param movie_name: :param release_time: :return: """ node1 = Node(DIRECTOR_LABEL, name=node_name1) node1['type'] = 'director' node2 = Node(ACTOR_LABEL, name=node_name2) # node3 = Node(MOVIE_LABEL, name=movie_name) # node3['url'] = url # # actor_movie_relation = Relationship(node2, ACTIN_LABEL, node3) # director_movie_relation = Relationship(node1, DIRECT_LABEL, node3) # self.graph.merge(actor_movie_relation, DEFAULT_LABEL, 'name') # self.graph.merge(director_movie_relation, DEFAULT_LABEL, 'name') # print(actor_movie_relation) # print(director_movie_relation) # if self.find_relation(node_name1, node_name2): # print('relation already existed, add count') # else: relation = Relationship(node1, COOPERATE_LABEL, node2) relation['count'] = 1 self.graph.merge(relation, DEFAULT_LABEL, 'name') # print("成功创建关系", node_name1, ',', COOPERATE_LABEL, ',', node_name2) def print(self, name, relation): """ 打印所有以名字为name的节点开始、具有relation关系的边的终节点的信息 :param name: :param relation: :return: """ print('##########') query = 'MATCH (n) WHERE n.name={name} RETURN n' params = dict(name=name) node = self.graph.evaluate(query, params) print(node) for rel in self.graph.match((node, ), relation): print(rel.end_node['name'], rel.end_node.labels, rel['movie_name'], rel['release_time']) def find_director_node(self, name): """ 查找具有某名字的节点,若图中有此节点则返回true,反之返回false :param name: :return: """ query = 'MATCH (n:Director) WHERE n.name={name} RETURN n' params = dict(name=name) node = self.graph.evaluate(query, params) if node is None: return False if self.graph.exists(node): return True else: return False def find_actor_node(self, name): """ 查找具有某名字的节点,若图中有此节点则返回true,反之返回false :param name: :return: """ query = 'MATCH (n:Actor) WHERE n.name={name} RETURN n' params = dict(name=name) node = self.graph.evaluate(query, params) if node is None: return False if self.graph.exists(node): return True else: return False def get_labeled_node(self, count=1): """ 获取具有某个标签的节点列表 打印节点数量 并返回该list :return: """ # 用CQL进行查询,返回的结果是list datas = self.graph.data('MATCH(p:Director) return p') # 目标节点数量 # print(len(datas)) # 数据类型为list # print(type(datas)) _count = 1 for data in datas: # data类型为dict # print(type(data)) # if _count > count: # break print(data) _count += 1 print('Total count of Director is', _count) return datas def find_relation_and_add_count(self, name1, name2): """ 查找分别以name1, name2为起始、终止节点的 CooperateWith 关系 若找到则对应count数加一 :param name1: :param name2: :return: """ sn = self.graph.find_one(DIRECTOR_LABEL, property_key='name', property_value=name1) en = self.graph.find_one(ACTOR_LABEL, property_key='name', property_value=name2) rel = self.graph.match(start_node=sn, rel_type=COOPERATE_LABEL, end_node=en) # print(rel) # print('--------') query = 'MATCH(n:Director)-[r:CooperateWith]->(m:Actor) WHERE n.name={name1} and m.name={name2} RETURN r' params = dict(name1=name1, name2=name2) relation = self.graph.evaluate(query, params) if relation is None: print('relation is none') self.add_relation(name1, name2) return False if self.graph.exists(relation): print('relation exists, add count') relation['count'] += 1 self.graph.push(relation) print(relation.start_node()['name'], '->', relation['count'], '->', relation.end_node()['name']) return True else: print('relation does not exist') return False def clear_graph(self): """ 清空图数据库 :return: """ self.graph.delete_all() def show_end_node(self, name, relation_label): """ 根据输入的起始节点名和关系标签,遍历全部对应关系,并打印终节点的属性群 :param name: :param relation_label: :param attrs: :return: """ query = 'MATCH (n) WHERE n.name={name} RETURN n' params = dict(name=name) node = self.graph.evaluate(query, params) if node is None: print('node is None!') return False if self.graph.exists(node): print(node) # 遍历此起始节点的全部关系,打印关系的个数 for rel in self.graph.match((node, ), relation_label): print(name, '->', rel['count'], '->', rel.end_node['name']) else: print('node not exists!') return False def get_coop_count(self): """ 获取全部导演、演员合作关系及次数并打印 :return: """ directors = self.get_labeled_node() # print(type(directors)) count = 1 for director in directors: if count > 1: break # print(director['p']['name']) self.show_end_node(director['p']['name'], COOPERATE_LABEL) count += 1 def get_cooperations(self): directors = self.get_labeled_node() # datas = [] for director in directors: query = 'MATCH (n) WHERE n.name={name} RETURN n' params = dict(name=director['p']['name']) node = self.graph.evaluate(query, params) if node is None: print('node is None!') return None if self.graph.exists(node): # 遍历此起始节点的全部关系,一一存入结果集并返回 for rel in self.graph.match(start_node=node, rel_type=COOPERATE_LABEL): data = { 'director': director['p']['name'], 'actor': rel.end_node()['name'], 'count': rel['count'] } # print("合作信息,", data) self.mm.save_data(Config.COOPERATION_TEMP, data) # datas.append(data) else: print('node not exists!') return None
class Group(object): def __init__(self): self.name = '' self.id = None self.about = '' self.mission_statement = '' self.is_open = None self.is_invite_only = False self.last_updated_date = '' # self.meeting_location = '' # self.next_meeting_date = None # self.next_meeting_time = None # self.creator = '' #by id # self.moderators = [] #by id self.website = '' self._graph_db = Graph(settings.DATABASE_URL) @property def group_properties(self): properties_dict = dict(self.__dict__) del properties_dict['_graph_db'] return properties_dict def set_group_properties(self, group_properties): for key, value in group_properties.iteritems(): setattr(self, key, value) def get_group(self): """ get the group info (attributes) based on the id :return: """ group_node = self.group_node group_properties = dict(group_node.properties) if not group_node is None: for key, value in group_properties.iteritems(): setattr(self, key, value) @property def group_node(self): """ get a group node based on the unique id attribute :return: neo4j.Node """ return self._graph_db.find_one(GraphLabel.STUDYGROUP, property_key='id', property_value=self.id) @property def group_interests(self): """ get user interests :return: list of interests """ group_interests = self._graph_db.match(start_node=self.group_node, rel_type=GraphRelationship.INTERESTED_IN, end_node=None) # create a list of tuples of interests and the users's relationship to them interests_list = [] for rel in group_interests: interest = Interest() interest.id = rel.end_node['id'] interest.get_interest_by_id() interest_dict = {} interest_dict = interest.interest_properties interests_list.append(interest_dict) # interests_list.append((item.end_node["name"], item["description"])) # return [item.end_node["name"] for item in user_interests] return interests_list @property def group_locations(self): """ :return: list of locations """ group_locations = self._graph_db.match(start_node=self.group_node, rel_type=GraphRelationship.LOCATED_IN, end_node=None) locations_list = [] for rel in group_locations: location_dict = {} location = Location() location.id = rel.end_node['id'] location_dict = dict(location.location_properties) locations_list.append(location_dict) # locations_list.append(item.end_node["formatted_address"]) return locations_list @property def group_members(self): group_member_nodes = self._graph_db.match(start_node=self.group_node, rel_type=GraphRelationship.MEMBER_OF, end_node=None) members_list = [] for rel in group_member_nodes: member_dict = {} # member = User() # member.id = rel.end_node['id'] # member_dict = dict(rel.end_node.properties) members_list.append(dict(rel.end_node.properties)) # members_list.append((member_node.end_node["name"], member_node.end_node["id"])) return members_list @property def group_creator(self): """ :return: dictionary object with creator user information """ group_creator = self._graph_db.match(start_node=self.group_node, rel_type=GraphRelationship.CREATED, end_node=None) creator_dict = {} for rel in group_creator: creator_dict = dict(rel.end_node.properties) return creator_dict @property def group_moderators(self): """ :return: list of user dictionary objects where the users are moderators """ group_moderators = self._graph_db.match(start_node=self.group_node, rel_type=GraphRelationship.MODERATES, end_node=None) moderators_list = [] for rel in group_moderators: moderators_list.append(dict(rel.end_node.properties)) return moderators_list def create_group(self): """ create new study group or circle :return: py2neo Node """ self.id = str(uuid.uuid4()) new_group_node = Node.cast(GraphLabel.STUDYGROUP, self.group_properties) try: self._graph_db.create(new_group_node) except: pass return new_group_node def add_interest(self, interest_id): """ link interests to a study group :return: list of group interests """ #TODO exception handling interest = Interest() interest.id = interest_id group_interest_relationship = Relationship(interest.interest_node_by_id, GraphRelationship.INTERESTED_IN, self.group_node) try: self._graph_db.create(group_interest_relationship) except: pass #TODO set properties on RELATIONSHIP return self.group_interests def update_group(self): group_node = self.group_node for key in self.group_properties.keys(): group_node[key] = self.group_properties[key] group_node.push() def allow_edit(self, auth_key): """ :return: """ allow = False moderators = self.group_moderators creator = self.group_creator if auth_key == creator['id']: allow = True else: for mod in moderators: if auth_key == mod['id']: allow = True return allow def create_conversation_for_group(self, group_id): #TODO this should go in group class pass # self.id = str(uuid.uuid4()) # self.created_date = datetime.date.today() # new_group_convo = Node.cast(GraphLabel.CONVERSATION, self.conversation_properties) # try: # self.graph_db.create(new_group_convo) # group = Group() # group.id = group_id # # create group started relationship # group_convo_relationship = Relationship(group.group_node, # GraphRelationship.STARTED, # self.conversation_node) # self.graph_db.create(group_convo_relationship) # except: # pass #TODO add exception handling #TODO close group def close_group(self): pass def matched_groups(self, match_string, limit): """ get a set of groups by name by :param match_string: partial name of group to search by :param limit: number of records to return in result set :return: dictionary of search results """ params = { 'match': '(?i)%s.*' % match_string, 'limit': limit } cypher_str = "MATCH (group:STUDYGROUP ) " \ "WHERE group.name =~ {match} " \ "RETURN group.name as name, group.id as id " \ "LIMIT {limit}" match_results = self._graph_db.cypher.execute(statement=cypher_str, parameters=params) root = {} root['count'] = 0 group_found = {} groups_list = [] for item in match_results: group_found['id'] = item.id group_found['name'] = item.name # self.id = item['id'] # self.get_user() # users_list.append(dict(self.user_properties)) groups_list.append(dict(group_found)) root['count'] += 1 root['groups'] = groups_list return root def add_conversation(self, subject, message): convo = Conversation() convo.subject = subject convo.message = message #TODO create conversation for group # convo.create_conversation_for_group(self.id) def update_conversation(self, subject, message, convo_id): pass #TODO add update conversation def group_for_json(self): # self # root = {} # root['id'] = self.id # root['name'] = self.name # root['description'] = self.description # root['is_invite_only'] = self.is_invite_only # root['is_open'] = self.is_open # root['meeting_location'] = self.meeting_location # root['next_meeting_date'] = self.next_meeting_date # root['next_meeting_time'] = self.next_meeting_time # root['interests'] = self.group_interests # root['users'] = self.group_members # # root['locations'] = self.group_locations return self.group_properties
def main(): # Defaults protocol = "http" hostName = "localhost" portNumber = 7474 dbPath = "/db/data/" userId = "" password = "" limit = 0 # limit = 0 means no limit, limit =n where n > 0 limits queries to at most n rows csvpath = "." nodeLabels = "" batchsize = 1000 try: opts, args = getopt.getopt(sys.argv[1:], "?", [ "help", "protocol=", "host=", "port=", "db=", "userid=", "password="******"limit=", "csvpath=", "nodelabels=" ]) except getopt.GetoptError: print "ERROR unknown option!" print "" usage() sys.exit(2) for opt, arg in opts: if opt in ('-?', '--help'): usage() sys.exit(0) elif opt == "--protocol": protocol = arg elif opt == "--host": hostName = arg elif opt == "--port": portNumber = arg elif opt == "--db": dbPath = arg elif opt == "--userid": userId = arg elif opt == "--password": password = arg elif opt == "--limit": limit = arg elif opt == "--csvpath": csvpath = arg elif opt == "--nodelabels": nodeLabels = arg else: print "ERROR: Unknown option", opt print "" usage() sys.exit(2) host = hostName + ":" + str(portNumber) url = protocol + "://" + host + dbPath print "Connect to", url if len(userId) > 0: authenticate(host, userId, password) graph = Graph(url) print "Connected:", graph.bound # Check if output directory exists if not os.path.isdir(csvpath): print "ERROR Directory doesn't exist", csvpath sys.exit(1) relationshipTables = { } # one table for each of the relationship types for the current label if len(nodeLabels) > 0: labels = nodeLabels.split(',') else: labels = graph.node_labels # Get list of labels from the database for label in labels: print "Get nodes for label:", label currentTable = table() nodecount = 0 while True: matchLimit = batchsize if limit > 0: if nodecount < limit: if nodecount + batchsize > limit: matchLimit = limit - nodecount else: break nodeCountCheck = nodecount # nodes = graph.find(label) nodes = graph.cypher.stream( "MATCH (n:" + str(label) + ") RETURN n ORDER BY id(n) SKIP {skip} LIMIT {limit}", { "skip": nodecount, "limit": matchLimit }) if not nodes: break for g_node in nodes: nodecount += 1 node = g_node.n row = node.properties.copy() row["nodeId"] = node._id currentTable.addRow(row) # get relationships if limit > 0: # limit is for n relationships per node, so you may end up with n^2 relationships! nodeRelationships = graph.match(start_node=node, limit=limit) else: nodeRelationships = graph.match(start_node=node) for rel in nodeRelationships: relTableName = str(label + "_" + rel.type) if relTableName in relationshipTables: relTable = relationshipTables[relTableName] else: relTable = table() relationshipTables[relTableName] = relTable relRows = rel.properties.copy() relRows["nodeId"] = node._id relRows["otherNodeId"] = rel.end_node._id relTable.addRow(relRows) print "\tNode count", nodecount, " at ", datetime.datetime.now() if nodecount == nodeCountCheck: print "No more nodes" break tableCsvFileName = label + ".csv" print "Export label CSV", tableCsvFileName currentTable.saveCsv(csvpath, tableCsvFileName) for relTableName in relationshipTables: relTable = relationshipTables[relTableName] relTableCsvFileName = relTableName + ".csv" print "Export relationship CSV", relTableCsvFileName relTable.saveCsv(csvpath, relTableCsvFileName) print "Finished"
class Organization(object): def __init__(self): self.name = '' self.id = '' self.mission_statement = '' self.about = '' self.is_open = False self.is_invite_only = False self.is_visible = True self.website = '' self._graph_db = Graph(settings.DATABASE_URL) @property def org_node(self): return self._graph_db.find_one(GraphLabel.ORGANIZATION, property_key='id', property_value=self.id) @property def org_properties(self): properties_dict = dict(self.__dict__) del properties_dict['_graph_db'] return properties_dict @property def org_interests(self): org_interests = self._graph_db.match(start_node=self.org_node, rel_type=GraphRelationship.INTERESTED_IN, end_node=None) interests_list = [] for rel in org_interests: interests_list.append(dict(rel.end_node.properties)) return interests_list @property def org_locations(self): """ list of locations for the org :return: list """ locations = self._graph_db.match(start_node=self.org_node, rel_type=GraphRelationship.LOCATED_IN, end_node=None) locations_list = [] for rel in locations: locations_list.append(dict(rel.end_node.properties)) return locations_list @property def org_members(self): """ list of users. user is a dictionary of properties list of the members of the organization :return: list of tuple of member name, email """ org_members_nodes = self._graph_db.match(start_node=self.org_node, rel_type=GraphRelationship.MEMBER_OF, end_node=None) org_members_list = [] for rel in org_members_nodes: org_members_list.append(dict(rel.end_node.properties)) # org_members_list.append((item.end_node["name"], item.end_node["email"])) return org_members_list def set_organization_attributes(self, org_properties): for key, value in org_properties.iteritems(): setattr(self, key, value) def get_organization(self): org_node = self.org_node org_properties = dict(org_node.properties) for key, value in org_properties.iteritems(): setattr(self, key, value) def create_organization(self): """ create a new organization :return: py2neo Node """ self.id = str(uuid.uuid4()) new_org_properties = self.org_properties new_org_node = Node.cast(GraphLabel.ORGANIZATION, new_org_properties) self._graph_db.create(new_org_node) return new_org_node def add_location(self, location_dict): """ add location relationship to organization if location does not exist, create the location node and then create relationship :param location_dict: dictionary object of location to add :return: """ location = Location() location.id = location_dict['id'] location_node = location.location_node_by_place_id if not location_node: location.set_location_properties(location_dict) location.create_location() location_node = location.location_node_by_place_id try: self._graph_db.create_unique(self.org_node, GraphRelationship.LOCATED_IN, location_node) except: pass #TODO exception handling def add_interest(self, interest_id): interest = Interest() interest.id = interest_id interest_node = interest.interest_node_by_id org_interest_relationship = Relationship(self.org_node, GraphRelationship.INTERESTED_IN, interest_node) try: self._graph_db.create_unique(org_interest_relationship) except: pass return self.org_interests def organization_relationships_for_json(self): root = {} root = dict(self.org_properties) root['interests'] = self.org_interests root['members'] = self.org_members root['locations'] = self.org_locations return root
Calculer: - check comment installer les algos de graph - le nb de connection in/out de chaque noeud, pour chaque D -APOC degree function - quels noeuds sont connectés / non connectés - ''' ******************************************** # This computes global in and out degree for all nodes len(graph.nodes.match(D0_status = "IN")) len(graph.nodes.match(D1_status = "IN")) len(graph.nodes.match(D2_status = "IN")) for node in graph.nodes.match(D0_status = "IN"): print(node['site_name'], len(graph.relationships.match((node,), r_type="LINKS_TO")), len(graph.relationships.match((None,node), r_type="LINKS_TO"))) graph.nodes.match(D0_status = "IN").first() lemonde_n = graph.nodes.match(site_name="lemonde.fr").first() Link_to_lemonde_r = graph.match(r_type="LINKS_TO", nodes=(None, lemonde_n)) for rel in Link_to_lemonde_r: print(rel['count_D2'], rel.nodes[0]['site_name']) # %% codecell # liste des sites que lemonde link avec le count for r in graph.match((graph.nodes.match(site_name="lemonde.fr").first(),)): print(r['count_D2'], r.end_node['site_name'])
class Cq(object): def __init__(self): """ :return: """ self.id = '' self.subject = '' self.message = '' self.created_date = '' self._graph_db = Graph(settings.DATABASE_URL) @property def cq_properties(self): """ :return: """ properties_dict = dict(self.__dict__) del properties_dict['_graph_db'] return properties_dict @property def cq_node(self): """ :return: """ if self.id != '': return self._graph_db.find_one(GraphLabel.CQ, property_key='id', property_value=self.id) @property def response_list(self): """ list of responses to this CQ :return: list of responses """ cq_response_relationship = self._graph_db.match(start_node=self.cq_node, rel_type=GraphRelationship.TO, end_node=None) response_list = [] for rel in cq_response_relationship: response = rel.end_node.properties user_response_relationship = self._graph_db.match_one(start_node=None, rel_type=GraphRelationship.RESPONDED, end_node=self.cq_node) user_node = user_response_relationship.start_node response['by'] = '%s / %s' % (user_node.properties['name'], user_node.properties['call_sign']) response_list.append(response) return response_list @staticmethod def create_cq(user_node, cq_dict): cq_dict['id'] = str(uuid.uuid4()) cq_dict['created_date'] = datetime.date.today() cq_node = Node.cast(GraphLabel.CQ, cq_dict) cq_node, = Graph(settings.DATABASE_URL).create(cq_node) cq_relationship = Relationship(user_node, GraphRelationship.SENT, cq_node) Graph(settings.DATABASE_URL).create_unique(cq_relationship) @staticmethod def most_recent_cqs(): params = { } cypher_str = "" match_results = Graph(settings.DATABASE_URL).cypher.execute(statement=cypher_str, parameters=params) cq_list = [] cq = {} for item in match_results: cq['id'] = item.id cq['subject'] = item.subject cq['message'] = item.message cq['created_date'] = item.created_date cq_list.append(cq) root = {} root['cqs'] = cq_list return root def response(self, response_id): """ response dictionary details including user details :param response_id: :return: dict with response details and a dict of the user who made the response """ response_node = self._graph_db.find_one(GraphLabel.RESPONSE, property_key='id', property_value=response_id) response_user_relationship = self._graph_db.match_one(start_node=None, rel_type=GraphRelationship.RESPONDED, end_node=response_node) response_dict = {} response_dict['response'] = response_node.auto_sync_properties response_dict['user'] = response_user_relationship.start_node.properties return response_dict
name=author).first() if existing_author_node: author_node = existing_author_node else: author_node = Node('Author', name=author) tx.create(author_node) authors_nodes.append(author_node) published_rel = Relationship(author_node, "PUBLISHED", pub_node) tx.create(published_rel) for author_node in authors_nodes: for other_author in authors_nodes: if not other_author == author_node: co_authorship_rel = g.match(start_node=author_node, rel_type="CO_AUTHORSHIP", end_node=other_author, bidirectional=True) co_authorship_rel_list = list(co_authorship_rel) if len(co_authorship_rel_list ) == 0: # Relationship does not exist new_co_authorship_rel = Relationship(author_node, "CO_AUTHORSHIP", other_author, count=1) tx.create(new_co_authorship_rel) tx.commit() print i, " publication(s) created" print ""
for index, row in RS_df.iterrows(): webmatch = graph.nodes.match('Website',site_name =row['site_name'].lower() ).first() if webmatch == None: results = db.run("MATCH (w:Website) WHERE $site_name IN w.D0_label RETURN w ",{"site_name":row['site_name'] }) trucmoche = 0 for r in results: trucmoche = trucmoche + 1 sn = r['w']['site_name'] webmatch = graph.nodes.match('Website',site_name =sn.lower() ).first() if trucmoche != 1: print("no node for Website:", row['site_name'], "not importing RS nodes" ) continue #print(nodematch['site_name']) # is there an entity ? rel = graph.match(r_type="OWNED_BY", nodes=(webmatch, None)) if len(rel)==0: entnode = Node('Entity', entity_name = webmatch['site_name']) entnode.__primarylabel__ = 'Entity' entnode.__primarykey__ = 'entity_name' OWNED_BY = Relationship.type("OWNED_BY") graph.merge(OWNED_BY(webmatch,entnode) ) rel = graph.match(r_type="OWNED_BY", nodes=(webmatch, None)) if len(rel)>1: print('several owners for this website : ',webmatch['site_name']) # TODO : Here are nodes with several owners ! What to do with that ? for r in rel: entitymatch=r.nodes[1] #twitter: if not pd.isnull(row['twit_final']): twitmatch = graph.nodes.match('Twitter', user_name = row['twit_final']).first()
class Diagnoser(): def __init__(self, description, disease, sep=',', alpha=0.2, S1_depth=1, S2_depth=5): self.description = description self.disease = disease self.S1_depth = S1_depth self.S2_depth = S2_depth self.sep = sep self.alpha = alpha self.symptoms = self.getSymptoms() self.symptomSet = self.getSymptomSet() # 获取所有可能的症状集合 self.graph = Graph("http://liublack.cn:7474", auth=("neo4j", "200001")) jieba.set_dictionary(SYMPTOM_DIC_PATH) def diagnose(self): node = self.graph.nodes.match('disease', name=self.disease).first() if node is None: raise Exception("no this disease.") symptoms = self._getSymptomsFromDisease([self.disease]) print(symptoms) frac = len(symptoms) prob = self.getSymptomsScore() / frac prob = prob if prob < 1 else 1 print(prob) return prob # def diagnose(self): # print(self.score(1)) # # 第一步,查找是否存在这个疾病 # node = self.graph.nodes.match('disease', name = self.disease).first() # if node is None: # raise Exception("no this disease.") # # 第二部,提取S1,S2 # S1 = self.getS1() # print("S1:", S1) # # S2 = self.getS2() # S2 = dict() # print("S2", S2) # # 第三步,获取所有用于计算概率的症状 # symptoms = set(S1).union(self.symptoms.intersection(set(S2))) # # 计算概率 # prob = 1 # for symptom in symptoms: # if symptom in S1 and symptom not in self.symptoms: # prob *= 1 - self.score(S1[symptom]) # elif symptom in S1 and symptom in self.symptoms: # prob *= self.score(S1[symptom]) # else: # prob *= self.score(S2[symptom]) # diseases = self._getDiseaseFromSymptoms(list(self.symptoms)) # prob *= 1 / len(diseases) + 1 # # prob /= (1 / 2) ** (len(symptoms) - 1) # print('prob:', prob) # return prob def score(self, depth): value, frac, n = (1, 1, 1) for i in range(depth): value += 1 frac += (1 + self.alpha)**n n += 1 value /= frac return value def getSymptomsScore(self): s = 0 for symptom in self.symptoms: try: statement = statement = 'match (p1:disease {name: "%s"}), (p2:symptom {name: "%s"}), p = shortestpath((p1)-[*..%d]-(p2)) return p, length(p) as len' % ( self.disease, symptom, self.S2_depth) cursor = self.graph.run(statement) s += self.score( cursor.current['len']) if cursor.forward() else 0 except Exception as e: print(e) return s def getS1(self): s = dict() try: statement = 'match (p1:disease {name: "%s"}), (p2:symptom), p = (p1)-[*..%d]-(p2) return p, length(p) as len' % ( self.disease, self.S1_depth) cursor = self.graph.run(statement) while cursor.forward(): s[cursor.current['p'].end_node['name']] = cursor.current['len'] except Exception as e: print(e) raise Exception('提取S1错误') return s def getS2(self): s = dict() try: statement = 'match (p1:disease {name: "%s"}), (p2:symptom), p = (p1)-[*..%d]-(p2) where length(p)>%d return p, length(p) as len' % ( self.disease, self.S2_depth, self.S1_depth) cursor = self.graph.run(statement) while cursor.forward(): # if cursor.current['len'] > self.S1_depth: s[cursor.current['p'].end_node['name']] = cursor.current['len'] except Exception as e: print(e) raise Exception('提取S2错误') return s def getSymptomSet(self): s = set() with open(SYMPTOM_DIC_PATH, 'r') as f: for line in f.readlines(): s.add(line.strip().split(' ')[0]) return s def getSymptoms(self): self.symptoms = set(self.description.strip().split(self.sep)) return self.symptoms def _calDiseaseScore(self, diseaseList, symptomList): scores = [] # 首先计算每一种症状对应的疾病数目 scoreSymptom = [] for symptom in symptomList: scoreSymptom.append(len(self._getDiseaseFromSymptoms([symptom]))) # 接下来计算每种疾病的置信度 for disease in diseaseList: score = 0 for idx, symptom in enumerate(symptomList): if self._existHaveRelationship(disease, symptom): score += 1.0 / scoreSymptom[idx] scores.append(score) return scores def _getSymptomsFromDisease(self, diseaseList): symptomSet = set() for disease in diseaseList: try: statement = 'MATCH (disease {name: "%s"})-[]->(n:symptom) RETURN n.name as name' % disease cursor = self.graph.run(statement) while cursor.forward(): symptomSet.add(cursor.current['name']) except Exception as e: print(e) return symptomSet def _getDiseaseFromSymptoms(self, symptomList): diseaseSet = set() for symptom in symptomList: node = self.graph.nodes.match('symptom', name=symptom).first() if node is None: continue rels = self.graph.match((None, node), r_type='d-s') for r in rels: diseaseSet.add(r.start_node['name']) return diseaseSet
class GraphDatabase(KnowledgeBase): def __init__(self, uri='http://localhost:7474', username='******', password='******'): self.uri = uri self.username = username self.password = password self.graph = Graph('http://localhost:7474', username='******', password='******') def _node_to_dict(self, node): '''将node转变为字典''' id = node.identity label = str(node.labels).split(':')[1] #node的label有点难取。。。 entity = {'id': id, 'label': label} for key, value in node.items(): entity[key] = value return entity # def _execute_entity_query(self,query:Text) -> List[Dict[Text,Any]]: # '''''' def get_entities(self, entity_type: Text = None, attributes: Optional[List[Dict[Text, Text]]] = None, limit: int = 10): if entity_type == None and attributes == None: raise Exception('GraphDatabase类:get_entities函数:实体类型和属性都没提供,报错') if attributes == None: nodes = self.graph.nodes.match(entity_type).limit(limit).all() else: attributes1 = attributes[0] id = None if 'id' in attributes1: id = attributes1['id'] attributes1.pop('id') if id == None: nodes = self.graph.nodes.match( entity_type, **attributes1).limit(limit).all() else: nodes = self.graph.nodes.match( entity_type, **attributes1).where('id(_)=' + str(id)).limit(limit).all() if nodes == None: print('没有查询到实体') return None nodes2list = [] for node in nodes: nodes2list.append(self._node_to_dict(node)) return nodes2list def get_attr_value(self, aimed_attribute, entity_id, entity_name=None): # node_matcher = NodeMatcher(graph=self.graph) if entity_name == None: nodes = self.graph.nodes.match().where('id(_)=' + str(entity_id)).first() else: nodes = self.graph.nodes.match( name=entity_name).where('id(_)=' + str(entity_id)).first() nodes_attr_dict = self._node_to_dict(nodes) if aimed_attribute in nodes_attr_dict.keys(): return nodes_attr_dict[aimed_attribute] return False pass def get_car_attr_value( self, aimed_attribute, car_series_name=None, car_series_id=None, ): if car_series_name == None: if car_series_id == None: raise Exception( 'GraphDatabase类:get_car_attr_value函数:车型id和名字都没提供,报错') else: # car_node = self.graph.nodes.match().where('id(_)='+str(car_series_id)).first() car_id = car_series_id else: if car_series_id == None: car_node = self.graph.nodes.match(name=car_series_name).first() else: car_node = self.graph.nodes.match( name=car_series_name).where('id(_)=' + str(car_series_id)).first() if car_node == None: return False #id错误,车名错误,或者id和车名不匹配时,找不到对应车系, car_id = car_node.identity relations = self.graph.match().where('ID(a) =' + str(car_id)).all() for relation in relations: end_node_dict = self._node_to_dict(relation.end_node) # print(end_node_dict) if aimed_attribute in end_node_dict.keys(): return end_node_dict[aimed_attribute] return None pass def query_relation2entity(self, entity, relation): entity_node = self.graph.nodes.match(name=entity).first() nodes = self.graph.match(nodes={entity_node}, r_type=relation).all() result = [] for node in nodes: result.append(node.start_node.get('name')) return result def query_attribute2entity(self, attributes): use_attributes = {} for k, v in attributes.items(): if v is not None: use_attributes[slot_neo4j_dict[k]] = v base_parameters = self.graph.nodes.match('车型基本参数', **use_attributes).all() entities = [] import sys for base_parameter in base_parameters: nodes = self.graph.match(nodes={base_parameter}, r_type='基本参数').all() for node in nodes: entities.append(node) result = [] for entity in entities: result.append(entity.start_node.get('name')) return list(set(result)) def query_entity2attribute(self, entity, relationship=None, c_attribute=None): e_attribute = c_attribute if relationship is not None and c_attribute is None: node = self.graph.nodes.match('车型', name=entity).first() r = self.graph.match(nodes={node}, r_type=relationship).first() return dict(r.end_node) if relationship is None and c_attribute is not None: # c_attribute 2 e_attribute for e, c in slot_neo4j_dict.items(): if c_attribute == c: e_attribute = e break # 将e_attribute映射为属性顶点 for k, v in schema.items(): for vv in v['attribute']: if vv == e_attribute: relationship = k # 英文转中文 relationship = slot_neo4j_dict[relationship] node = self.graph.nodes.match('车型', name=entity).first() r = self.graph.match(nodes={node}, r_type=relationship).first() result = {} result[c_attribute] = dict(r.end_node)[c_attribute] return result
class GotGraph(object): """ This object provides a set of helper methods for creating and retrieving nodes and relationships from a Neo4j database holding information about players, teams, fans, comments and their relationships. """ # Note: # I tend to avoid object mapping frameworks. Object mapping frameworks are fun in the beginning # but tend to be annoying after a while. So, I did not create types Player, Team, etc. # # Connects to the DB and sets a Graph instance variable. # Also creates a NodeMatcher and RelationshipMatcher, which are a py2neo framework classes. def __init__( self, auth=('neo4j', 'dbuserdbuser'), host='localhost', port=7687, secure=False, ): self._graph = Graph(secure=secure, bolt=True, auth=auth, host=host, port=port) self._node_matcher = NodeMatcher(self._graph) self._relationship_matcher = RelationshipMatcher(self._graph) def run_q(self, qs, args): """ :param qs: Query string that may have {} slots for parameters. :param args: Dictionary of parameters to insert into query string. :return: Result of the query, which executes as a single, standalone transaction. """ try: tx = self._graph.begin(autocommit=False) result = self._graph.run(qs, args) return result except Exception as e: print("Run exaception = ", e) def run_match(self, labels=None, properties=None): """ Uses a NodeMatcher to find a node matching a "template." :param labels: A list of labels that the node must have. :param properties: A dictionary of {property_name: property_value} defining the template that the node must match. :return: An array of Node objects matching the pattern. """ #ut.debug_message("Labels = ", labels) #ut.debug_message("Properties = ", json.dumps(properties)) if labels is not None and properties is not None: result = self._node_matcher.match(labels, **properties) elif labels is not None and properties is None: result = self._node_matcher.match(labels) elif labels is None and properties is not None: result = self._node_matcher.match(**properties) else: raise ValueError( "Invalid request. Labels and properties cannot both be None.") # Convert NodeMatch data into a simple list of Nodes. full_result = [] for r in result: full_result.append(r) return full_result def find_nodes_by_template(self, tmp): """ :param tmp: A template defining the label and properties for Nodes to return. An example is { "label": "Fan", "template" { "last_name": "Ferguson", "first_name": "Donald" }} :return: A list of Nodes matching the template. """ labels = tmp.get('label', None) props = tmp.get("template", None) result = self.run_match(labels=labels, properties=props) return result def create_node(self, label, **kwargs): n = Node(label, **kwargs) tx = self._graph.begin(autocommit=True) tx.create(n) return n # Given a UNI, return the node for the Fan. def get_character(self, character_id): n = self.find_nodes_by_template({ "label": "Character", "template": { "character_id": character_id } }) if n is not None and len(n) > 0: # I should throw an exception here if there is more than 1. n = n[0] else: n = None return n def get_related_characters(self, ch_id, r_kind): t = self.get_character(ch_id.upper()) nodes = set() nodes.add(t) n = self._relationship_matcher.match(nodes, r_type=r_kind.upper()) return n def create_character_relationship(self, source_id, target_id, label): """ Create a SUPPORTS relationship from a Fan to a Team. :param uni: The UNI for a fan. :param team_id: An ID for a team. :return: The created SUPPORTS relationship from the Fan to the Team """ f = self.get_character(source_id) t = self.get_character(target_id) l = label.upper() r = Relationship(f, l, t) tx = self._graph.begin(autocommit=True) tx.create(r) return r def get_appearance(self, player_id, team_id, year_id): """ Get the information about appearances for a player and team. :param player_id: player_id :param team_id: team_id :param year_id: The year for getting appearances. :return: """ try: # Get the Nodes at the ends of the relationship representing appearances. p = self.get_player(player_id) t = self.get_team(team_id) # Run a match looking for relationships of a specific type linking the nodes. rm = self._graph.match(nodes=[p, t], r_type="APPEARED") result = [] # If there is a list of relationships. if rm is not None: for r in rm: # The type will be a class APPEARED() because of the OO mapping. node_type = type(r).__name__ year = r['year'] # If the type and year are correct, add to result if node_type == "APPEARED" and (year == year_id or year_id is None): result.append(r) return result else: return None except Exception as e: print("get_appearance: Exception e = ", e) raise e # Create an APPEARED relationship from a player to a Team def create_appearance_all(self, player_id, team_id, year, games): """ :param player_id: O :param team_id: :param year: :param games: :return: """ try: tx = self._graph.begin(autocommit=False) q = "match (n:Player {player_id: '" + player_id + "'}), " + \ "(t:Team {team_id: '" + team_id + "'}) " + \ "create (n)-[r:APPEARED { games: " + str(games) + ", year : " + str(year) + \ "}]->(t)" result = self._graph.run(q) tx.commit() except Exception as e: print("create_appearances: exception = ", e) # Create a FOLLOWS relationship from a Fan to another Fan. def create_follows(self, follower, followed): f = self.get_fan(follower) t = self.get_fan(followed) r = Relationship(f, "FOLLOWS", t) tx = self._graph.begin(autocommit=True) tx.create(r) def get_comment(self, comment_id): """ :param comment_id: Comment ID :return: Comment """ n = self.find_nodes_by_template({ "label": "Comment", "template": { "comment_id": comment_id } }) if n is not None and len(n) > 0: n = n[0] else: n = None return n def create_comment(self, uni, comment, team_id=None, player_id=None): """ Creates a comment :param uni: The UNI for the Fan making the comment. :param comment: A simple string. :param team_id: A valid team ID or None. team_id and player_id cannot BOTH be None. :param player_id: A valid player ID or None :return: The Node representing the comment. """ if uni is None or comment is None or (player_id is None and team_id is None): raise ValueError("create_comment: invalid input.") comment_id = str( uuid.uuid4()) # Generate a UUID. Will explain in class. fan = None team = None player = None tx = None try: tx = self._graph.begin( ) # We are going to make a transactional update. fan = self.get_fan(uni) # Get the node for the Fan. if fan is None: raise ValueError("create_comment: Fan node node found.") if team_id is not None: team = self.get_team(team_id) if team is None: raise ValueError("create_comment: Team node node found.") if player_id is not None: player = self.get_player(player_id) if player is None: raise ValueError("create_comment: Player node node found.") c = Node("Comment", comment_id=comment_id, comment=comment) tx.create(c) pc = Relationship(fan, "COMMENT_BY", c) tx.create(pc) if player is not None: pr = Relationship(c, "COMMENT_ON", player) tx.create(pr) if team is not None: p2 = Relationship(c, "COMMENT_ON", team) tx.create(p2) tx.commit() return c except Exception as e: if tx: tx.rollback() raise RuntimeError( "create_comment: Something evil happened., e = " + str(e)) def create_sub_comment(self, uni, origin_comment_id, comment): """ Create a sub-comment (response to a comment or response) and links with parent in thread. :param uni: ID of the Fan making the comment. :param origin_comment_id: Id of the comment to which this is a response. :param comment: Comment string :return: Created comment. """ if uni is None or origin_comment_id is None or comment is None: raise ValueError("create_sub_comment: invalid input.") comment_id = str( uuid.uuid4()) # Generate a UUID. Will explain in class. fan = None origin_comment = None tx = None try: tx = self._graph.begin( ) # We are going to make a transactional update. fan = self.get_fan(uni) # Get the node for the Fan. if fan is None: raise ValueError("create_sub_comment: Fan node node found.") origin_comment = self.get_comment(origin_comment_id) if origin_comment is None: raise ValueError( "create_sub_comment: Original comment node not found.") c = Node("Comment", comment_id=comment_id, comment=comment) tx.create(c) sc = Relationship(c, "RESPONSE_TO", origin_comment) tx.create(sc) pc = Relationship(fan, "RESPONSE_BY", c) tx.create(pc) tx.commit() except Exception as e: if tx: tx.rollback() raise RuntimeError( "create_comment: Something evil happened., e = " + str(e)) def get_sub_comments(self, comment_id): """ :param comment_id: The unique ID of the comment. :return: The sub-comments. """ q = "match (c:Comment {comment_id: {cid}})<-[response:RESPONSE_TO]-(sc:Comment) return sc,response,c" c = self._graph.run(q, cid=comment_id) return c def get_roster(self, team_id, year_id): q = "match (t:Team {team_id: {tid}})<-[a:APPEARED {year: {yid}}]-(p:Player) " + \ " return t.team_id, t.team_name, a.year, a.games, p.player_id, p.last_name, p.first_name" c = self._graph.run(q, tid=team_id, yid=year_id) return c def get_player_comments(self, player_id): """ Gets all of the comments associated with a player, all of the comments on the comment and comments on the comments, etc. Also returns the Nodes for people making the comments. :param player_id: ID of the player. :return: Graph containing comment, comment streams and commenters. """ q = 'match (fan)-[by:COMMENT_BY]->(comment)-[on:COMMENT_ON]->(player:Player {player_id: {pid}}) ' + \ 'return fan.uni, fan.last_name, fan.first_name, comment.comment_id, comment.comment, ' + \ " player.player_id, player.last_name, player.first_name " result = self._graph.run(q, pid=player_id) return result def get_player_comments_g(self, player_id): """ Gets all of the comments associated with a player, all of the comments on the comment and comments on the comments, etc. Also returns the Nodes for people making the comments. :param player_id: ID of the player. :return: Graph containing comment, comment streams and commenters. """ q = 'match (fan)-[by:COMMENT_BY]->(comment)-[on:COMMENT_ON]->(player:Player {player_id: {pid}}) ' + \ 'return fan, by, comment, on, player ' result = self._graph.run(q, pid=player_id) return result def get_team_comments(self, team_id): """ Gets all of the comments associated with a teams, all of the comments on the comment and comments on the comments, etc. Also returns the Nodes for people making the comments. :param player_id: ID of the team. :return: Graph containing comment, comment streams and commenters. """ t = self.get_team(team_id) nodes = set() nodes.add(t) n = self._relationship_matcher.match(nodes, r_type="COMMENT_ON") return n def get_players_by_team(self, team_id): """ :param team_id: Team ID :return: List of Nodes representing players who played for the team. """ q = "match (p:Player)-[r:APPEARED]->(t:Team) where t.team_id={tid} return p,r,t" result = self._graph.run(q, tid=team_id) result = result.data() ans = [] for r in result: current = dict(r['p'].items()) current['year'] = r['r']['year'] ans.append(current) return ans
to_type = "grey" print(from_type, from_name, edge_type, to_type, to_name) from_node = graph.merge_one(from_type.strip(), "name", from_name.strip()) to_node = graph.merge_one(to_type.strip(), "name", to_name.strip()) from_to = Relationship(from_node, edge_type, to_node) graph.create_unique(from_to) # get nodes with degree nodes = [] for label in graph.node_labels: for p in graph.find(label): node = {"id": p.ref.split("/")[-1], "label": p["name"], "title": p["name"], "value": p.degree, "group": label} nodes.append(node) with open("report/nodesnetlog.js", "w") as f: f.write("var nodesraw = " + dumps(nodes, indent=2) + ";") # get edges edges = [] for r in graph.match(): edge = {"to": r.end_node.ref.split("/")[-1], "from": r.start_node.ref.split("/")[-1] } edges.append(edge) with open("report/edgesnetlog.js", "w") as f: f.write("var edgesraw = " + dumps(edges, indent=2) + ";")