python使用py2neo查询Neo4j的节点、关系及路径

一、连接Neo4j数据库

本文中会用到多种数据类型,在此一并引用

<import numpy as np
import pandas as pd
from py2neo import Node,Relationship,Graph,Path,Subgraph
from py2neo import NodeMatcher,RelationshipMatcher

配置Neo4j数据库的访问地址、用户名和密码:

neo4j_url = '访问地址'
user = '用户名'
pwd = '密码'

在此时间段之前访问数据库的方式为:

graph = Graph(neo4j_url, username=user, password=pwd)

在此时间段之后的版本访问数据库的方式为(就是这么不兼容):

graph = Graph(neo4j_url,  auth=(user, pwd))

以下图为例:

  • 图中包含一些Person节点,每个Person节点有name、age、work属性;
  • 其中“赵赵”节点是多label的节点,除了有Person标签,它还有Teacher标签;
  • Person和Person节点之间有同事、邻居、学生、老师等关系;
  • 图中还有一些Location节点,它们之间有包含关系;
  • Person节点和Location节点之间有“到访”关系,“到访”关系具有date和stay_hours两个属性。

二、 通过graph.schema查询图中节点和关系有哪些类型

查看节点的类型用graph.schema.node_labels,查看关系的类型用graph.schema.relationship_types,它们的返回值类型都是frozenset,是不能增删元素的集合。

>>>graph.schema.node_labels
frozenset({'Location', 'Person', 'Teacher'})
>>>graph.schema.relationship_types
frozenset({'到访', '包含', '同事', '学生', '老师', '邻居'})

三、使用NodeMatcher查询节点

首先创建一个NodeMatcher对象,用match来指明要匹配哪种label的节点,用where来表示筛选条件(有两种方法)。需要注意的是,匹配成功返回的是NodeMatcher的对象,要转化成Node对象,可以用first取出符合条件的第一个节点,或者转化成节点的list。

>>>node_matcher = NodeMatcher(graph)
>>>node = node_matcher.match("Person").where(age=20).first()
>>>node
Node('Person', age=20, name='李李', work='我们')
>>>nodes = list(node_matcher.match("Person").where(age=35))
>>>nodes
[Node('Person', age=35, name='王王', work='我们')]

where条件有两种写法,一种是把要匹配的属性和值写成key=value的形式,例如上面的where(age=20),这种写法只能按照值是否完全一致来匹配,不能按照值的大小来筛选,如果写成下面这样是会报错的:

node = node_matcher.match("Person").where(age>20).first() # 错误
想要按照值的大小筛选或者做一些字符串的模糊匹配,可以把条件表达式写成一个字符串,整体放在where语句中,在这个字符串中,可以用 _ 来代指匹配到的节点。下面两个例子,第一个是匹配work属性为“月亮XX”模式的Person节点,另一个是匹配age大于20的Person节点。

>>>node = node_matcher.match("Person").where("_.work =~ '月亮.*'").first()
>>>node
Node('Person', 'Teacher', age=45, name='赵赵', work='月亮中学')
>>>nodes = list(node_matcher.match("Person").where("_.age > 20"))
>>>nodes
[Node('Person', age=35, name='王王', work='我们'),
 Node('Person', age=30, name='张张', work='我们'),
 Node('Person', 'Teacher', age=45, name='赵赵', work='月亮中学')]

将NodeMatcher返回的结果转化为Node数据类型或者Node的list之后,访问其中的属性也就十分简单了,如上面最后一例的结果,访问其中第一个节点的name属性:

>>>nodes[0]['name']
'王王'

四、 使用RelationshipMatcher查询关系

RelationshipMatcher的match方法有三个及以上参数:

  • 第一个参数是节点的序列或者set,可以为None,为None表示任意节点均可;
  • 第二个参数是关系的类型,可以为None,为None表示任意类型的关系均可;
  • 第三个参数开始是要匹配的属性,写成key=value的形式。

match方法的返回值是RelationshipMatcher类型,需要通过first转化成Relationship数据结构,或者转化为list。

举例说明

列1:比如想要查询“李李”节点的所有关系。先查询出节点,再查询节点的关系,r_type=None表示任意类型的关系均可。返回的关系包括到访、同事。

>>>node1 = node_matcher.match("Person").where(name='李李').first()
>>>relationship = list(relationship_matcher.match([node1], r_type=None))
>>>relationship
[到访(Node('Person', age=20, name='李李', work='我们'), Node('Location', name='禄口机场'), date='2021/7/16', stay_hours=1),
 同事(Node('Person', age=20, name='李李', work='我们'), Node('Person', age=30, name='张张', work='我们')),
 同事(Node('Person', age=20, name='李李', work='我们'), Node('Person', age=35, name='王王', work='我们'))]

例2:查询“李李”和“张张”的关系,两个节点的顺序表示了要匹配的关系的方向。所以在整个图中“李李”和“张张”节点之间的同事关系是双向的,但是查询结果只给出了从“张张”节点到“李李”节点的一条关系。

>>>node1 = node_matcher.match("Person").where(name='李李').first()
>>>node2 = node_matcher.match("Person").where(name='张张').first()
>>>relationship = list(relationship_matcher.match((node2,node1), r_type=None))
>>>relationship
[同事(Node('Person', age=30, name='张张', work='我们'), Node('Person', age=20, name='李李', work='我们'))]

例3:询图中某一类关系,第一个参数为None,第二个参数r_type指定关系类型,这里查询了图中所有的同事关系。

>>>relationship = list(relationship_matcher.match(None, r_type='同事'))
>>>relationship
[同事(Node('Person', age=20, name='李李', work='我们'), Node('Person', age=30, name='张张', work='我们')),
 同事(Node('Person', age=20, name='李李', work='我们'), Node('Person', age=35, name='王王', work='我们')),
 同事(Node('Person', age=35, name='王王', work='我们'), Node('Person', age=20, name='李李', work='我们')),
 同事(Node('Person', age=30, name='张张', work='我们'), Node('Person', age=20, name='李李', work='我们'))]

例4: 在查询关系时按照属性的值筛选,可以将该属性写为key=value的形式作为match方法的第三个参数。这里,查询图中的到访关系,并且stay_hours属性为1。

>>>relationship = list(relationship_matcher.match(None, r_type='到访', stay_hours=1))
>>>relationship
[到访(Node('Person', age=20, name='李李', work='我们'), Node('Location', name='禄口机场'), date='2021/8/24', stay_hours=1)]

虽然Py2neo的手册上没有写,但其实RelationshipMatcher也可以接上where方法,按照属性的值筛选关系。上面这个例子也可以写作下面这种形式,效果是一样的。

relationship = list(relationship_matcher.match(None, r_type='到访').where(stay_hours=1))
同样,在where方法中也可以写一个字符串表达式,实现按值大小来筛选关系。例如要筛选出所有到访关系,且stay_hours>=1的关系时,可以这样写:

>>>relationship = list(relationship_matcher.match(None, r_type='到访').where("_.stay_hours>=1"))
>>>relationship
[到访(Node('Person', age=20, name='李李', work='我们'), Node('Location', name='禄口机场'), date='2021/8/24', stay_hours=1),
 到访(Node('Person', age=20, name='刘刘', work='地球电子商务公司'), Node('Location', name='禄口机场'), date='2021/8/24', stay_hours=4)]

如何访问返回的结果中的各个属性呢,Relationship其实是包含了一对起止节点:start_nodeend_node,包含了关系的类型,而关系的属性是以字典形式存在的,可以用get方法来获取属性的值。
获取关系的起止节点:

>>>print(relationship[0].start_node['name'])
>>>print(relationship[0].end_node['name'])
李李
禄口机场

获取关系的类型的文本字符串

>>>print(relationship[0])
>>>print(type(relationship[0]).__name__)
(李李)-[:到访 {date: '2021/8/24', stay_hours: 1}]->(禄口机场)
到访

获取关系中的属性和值

>>>print(relationship[0].keys())
>>>print(relationship[0].values())
>>>print(relationship[0].get('date'))
dict_keys(['date', 'stay_hours'])
dict_values(['2021/8/24', 1])
2021/8/24

五、通过执行Cypher语句查询

NodeMatcher和RelationshipMatcher能够表达的匹配条件相对简单,更加复杂的查询还是需要用Cypher语句来表达。Py2neo本身支持执行Cypher语句的执行,可以将复杂的查询写成Cypher语句,通过graph.run方法查询,返回的结果可以转化为pandas.DataFrame或者pandas.Series对象,从而和其他数据分析工具无缝衔接。

例如:要查询Person节点,并满足work属性为“我们”。Cypher语句中可以使用WHERE接条件表达式,使用AS将返回的属性改名,返回多个属性时,用xxx AS x, yyy AS y。graph.run方法之后再接to_data_frame()可以将返回的数据变成pandas的DataFrame对象,并且用AS改过的属性名即为DataFrame中的列名。

cypher_ = "MATCH (n:Person) \
WHERE n.work='我们' \
RETURN n.name AS name, n.age AS age "

df = graph.run(cypher_).to_data_frame() # pd.DataFrame

例2:查询一个已知节点和其他哪些节点有关系,有什么样的关系。Cypher语言查询关系时用 < 或者 > 表示方向,这里需要返回type(r),直接返回r的话结果里是空值。

>>>cypher_ = "MATCH (n:Person)-[r]->(m:Person) \
WHERE n.name='李李' \
RETURN type(r) AS type,m.name AS name"
>>>df = graph.run(cypher_).to_data_frame() # pd.DataFrame

例3:Cypher语言还可以查询路径,因为不确定返回的路径数量,所以最好先将结果转化为pandas.Series,再遍历访问其中每条路径的节点和关系。
这里查询的是“赵赵”节点和“王王”节点之间的关系路径,关系指定为同事或邻居,关系不超过4层。

>>>cypher_ = "MATCH path=(m:Person)-[:同事|邻居*1..4]->(n:Person) \
WHERE m.name='赵赵' AND n.name='王王' \
RETURN path"
>>>s = graph.run(cypher_).to_series()
>>>print(len(s))
>>>s[0]

Path(Node('Person', 'Teacher', age=45, name='赵赵', work='月亮中学'),
邻居(Node('Person', 'Teacher', age=45, name='赵赵', work='月亮中学'),
Node('Person', age=30, name='张张', work='我们')),
同事(Node('Person', age=30, name='张张', work='我们'),
Node('Person', age=20, name='李李', work='我们')),
同事(Node('Person', age=20, name='李李', work='我们'),
Node('Person', age=35, name='王王', work='我们')))

这里查询到的关系路径数量仅有1条。从上图的结果中也可以看出来,Path是一个比较复杂的结构,Path中的节点和关系分别用nodes和relationships表示,并且是按照路径上节点和关系的顺序分别存放的。这里给出一段示例代码,对每一个路径都做了直接打印path数据结构和自己组织路径文本。

for path in s:
    # 直接打印path
    print(path)
    # 获取路径中的节点和关系
    nodes = path.nodes
    relationshis = path.relationships
    # 自己组织路径文本
    path_text = ""
    for n,r in zip(nodes, relationshis):
        # 每次加入一个节点和一个关系的类型
        path_text += "{} - {} - ".format(n['name'], type(r).__name__)
    # 别忘了最后一个节点
    path_text += nodes[-1]['name'] + '\n'
    print(path_text)

运行这段代码得的结果如下所示,上面一行是直接打印路径的结果,下面一行是自己组织文本得到的结果。

(赵赵)-[:邻居 {}]->(张张)-[:同事 {}]->(李李)-[:同事 {}]->(王王)
赵赵 - 邻居 - 张张 - 同事 - 李李 - 同事 - 王王

使用Py2neo查询Neo4j中的节点、关系和路径时,条件简单的查询可以通NodeMatcher和RelationshipMatcher来实现。而较为复杂的查询,可以写成Cypher语句来查询,查询结果可以转化为pandas的DataFrame或者Series数据类型,与其他数据分析工具结合

以上就是python使用py2neo查询Neo4j的节点、关系及路径的详细内容,更多关于python py2neo的资料请关注我们其它相关文章!

(0)

相关推荐

  • 手把手带你用python爬取小姐姐私房照

    目录 如何用Python搞到小姐姐私房照 目标站点 开发环境 效果预览 正式教程 一.第三方库安装 二.爬虫的基本套路 分析目标站点 请求网站获取数据 解析数据 保存数据 写在最后 如何用Python搞到小姐姐私房照 本文纯技术角度出发,教你如何用Python爬虫获取百度图库海量照片--技术无罪. 学会获取小姐姐私房照同理可得也能获取其他的照片,技术原理是一致的. 目标站点 百度图片使用关键字搜索 小姐姐私房照 https://image.baidu.com/ 开发环境 系统:Windows10

  • Python使用Py2neo创建Neo4j的节点、关系及路径

    目录 一.安装Py2neo 二.连接Neo4j数据库 1. 使用graph.run执行Cypher语句创建节点 2. 使用Node数据结构创建节点 3. 使用Node.Relationship和Subgraph数据结构创建节点和关系 三.性能对比 一.安装Py2neo 使用pip安装Py2neo,执行: pip install py2neo 查看已安装的Py2neo是什么版本的: pip show py2neo 二.连接Neo4j数据库 本文中会用到多种数据类型,在此一并引用 import nu

  • Python time.time()方法

    目录 描述 返回值 实例 备注 总结 描述 Python time time()返回当前时间的时间戳(1970纪元后经过的浮点秒数). 突然想看时间了,打开cmd发现脑中空荡,Java和Python的Time类全忘了,我留下了无助的眼泪o(╥﹏╥)o. 语法 time()方法语法: time.time() 返回值 返回当前时间的时间戳(1970纪元后经过的浮点秒数). 实例 以下实例展示了 time() 函数的使用方法: #!/usr/bin/python import time print "

  • python中bottle使用实例代码

    模仿学习同事的代码来写的,主要是搞懂python中如何来组织包,如何调用包,如何读取配置文件,连接数据库,设置路由,路由分组.(注:使用的是python3.6) 整体目录设计如下: 根据调用层级从上往下来说: 首先项目根目录下的main.py是整个程序的入口,主要作用启动http服务器,调用分组路由. main.py import bottle from confg.conf import CONF from api.user import User db_url = CONF.db.url d

  • Python使用py2neo操作图数据库neo4j的方法详解

    本文实例讲述了Python使用py2neo操作图数据库neo4j的方法.分享给大家供大家参考,具体如下: 1.概念 图:数据结构中的图由节点和其之间的边组成.节点表示一个实体,边表示实体之间的联系. 图数据库:以图的结构存储管理数据的数据库.其中一些数据库将原生的图结构经过优化后直接存储,即原生图存储.还有一些图数据库将图数据序列化后保存到关系型或其他数据库中. 之所以使用图数据库存储数据是因为它在处理实体之间存在复杂关系的数据具有很大的优势.使用传统的关系型数据库在处理数据之间的关系时其实很不

  • python利用文件读写编写一个博客

    代码展示 import random import json import time import os     def zhuce():     print("*********************正在注册*********************")     try:         users = readfile()     except:         fa = open(r'test.json', "w",encoding="utf-8&

  • Python接口自动化之接口依赖

    目录 一.场景说明 二.token处理思路 三.JsonPath基本用法 1.JsonPath介绍 2.JsonPath语法 3.JsonPath源码 4.JsonPath实战 四.token依赖实例 ⑤接下来编写函数,获取登录接口返回值并提取token和token_type进行拼接 .这里要使用jsonpath模块提取返回的token和token_type. ⑥最后定义类,将token作为类属性,整体代码如下: ⑦充值接口携带token请求. 总结: 一.场景说明 在面试接口自动化时,经常会问

  • python使用py2neo查询Neo4j的节点、关系及路径

    一.连接Neo4j数据库 本文中会用到多种数据类型,在此一并引用 <import numpy as np import pandas as pd from py2neo import Node,Relationship,Graph,Path,Subgraph from py2neo import NodeMatcher,RelationshipMatcher 配置Neo4j数据库的访问地址.用户名和密码: neo4j_url = '访问地址' user = '用户名' pwd = '密码' 在此

  • python使用py2neo创建neo4j的节点和关系

    1.核心代码 使用py2neo连接neo4j的方法: from py2neo import Graph graph = Graph("http://localhost:7474", auth=("neo4j", "neo4j")) graph.delete_all()  # 删除已有的所有内容 根据dict创建Node: from py2neo import Node node = Node(**{"key":"va

  • python 实现查询Neo4j多节点的多层关系

    需求:查询出满足3人及3案有关系的集合 # -*- coding: utf-8 -*- from py2neo import Graph import psycopg2 # 二维数组查找 def find(target, array): for i, val in enumerate(array): for j, temp in enumerate(val): if temp == target: return True; return False graph = Graph(host="192

  • Python算法之求n个节点不同二叉树个数

    问题 创建一个二叉树 二叉树有限多个节点的集合,这个集合可能是: 空集 由一个根节点,和两棵互不相交的,分别称作左子树和右子树的二叉树组成 创建二叉树: 创建节点 再创建节点之间的关系 Python代码示例 # !/usr/bin/env python # -*-encoding: utf-8-*- # author:LiYanwei # version:0.1 class TreeNode(object): def __init__ (self, data, left = None, righ

  • python通过socket查询whois的方法

    本文实例讲述了python通过socket查询whois的方法.分享给大家供大家参考.具体实现方法如下: import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('whois.networksolutions.com', 43)) s.send('sina.com.cn \r\n') while 1: v = s.recv(1024) if v == '' or v == None: break

  • Javascript节点关系实例分析

    本文实例分析了Javascript的节点关系.分享给大家供大家参考.具体如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>节点关系</title> <script typ

  • python下如何查询CS反恐精英的服务器信息

    前言 服务器的相关知识曾经让我非常困惑.我相信还有很多的Python开发者和我有着类似的遭遇.本文主要介绍了python下如何查询CS反恐精英的服务器信息,有需要的可以参考学习. CS反恐精英1.5版本示例代码 #!/bin/env python import urllib2, base64, sys, getopt import re import socket def Usage (): print "Usage: hlds.py -h 127.0.0.1 -p 27015" sy

  • Python获取SQLite查询结果表列名的方法

    本文实例讲述了Python获取SQLite查询结果表列名的方法.分享给大家供大家参考,具体如下: 获得查询结果表的列名: db = sqlite.connect('data.db') cur = db.cursor() cur.execute("select * from table") col_name_list = [tuple[0] for tuple in cur.description] print col_name_list 获得所有列名: cur.execute(&quo

随机推荐