首页 > 数据库 >Neo4j图数据库快速使用

Neo4j图数据库快速使用

时间:2023-06-03 12:11:33浏览次数:44  
标签:name 数据库 主播 merge User Neo4j neo4j 快速 match

针对这个项目中用到的技术组件,只有filebeat和neo4j我们没有使用过
不过filebeat比较简单,类似于flume,在使用的时候主要是写配置文件,所以在后面用到的时候我们再具体分析。
下面我们来学习一下neo4j的使用,快速了解它并掌握它的常见用法。

Neo4j介绍

Neo4j是一个高性能的图数据库,它和普通的关系型数据库是不一样的,它里面侧重于存储关系数据。
针对各种明星之间错综复杂的关系,如果使用mysql这种数据库存储,在查询所有人之间的关系的时候是非常复杂的,
但是使用Neo4j这种数据库,只需要一条命令就可以了。

它是一个嵌入式的、基于磁盘的、具备完全的事务特性的持久化引擎,它将结构化数据存储在网络(从数学角度叫做图)上而不是表中

目前neo4j有两种发行版,
一个是商业版:支持集群
另一个是社区版:只支持单机
目前我们平台用户量在三四千万的规模,单机的性能也是足够使用的。
等后期单机无法支撑之后再考虑使用商业版的。

Neo4j安装部署

Neo4j支持在windows和linux中进行安装
由于在实际工作中肯定是在linux中进行安装,所以在这我们就直接在linux中安装了。

下载地址,这里我们使用3.5.21社区版,可能会很慢。

注意:官网只能下载最新版本,没找到下载之前版本的地方。

修改配置 conf/neo4j.conf

dbms.connectors.default_listen_address=bigdata01
dbms.connectors.default_advertised_address=bigdata01

注意:这里的bigdata01是当前机器的主机名

启动和停止

bin/neo4j start
bin/neo4j stop

访问neo4j的web页面 http://bigdata01:7474/ 默认账号密码 neo4j/neo4j

image

注意:第一次访问的时候会提示修改密码,建议改为admin

Neo4j案例

Neo4j可以很方便的展示一些人物或者事物之间的错综复杂的关系

image

这张图里面展示了这些人物之间的关系,使用这种展示形式看起来是很清晰的,也方便理解
后期如果我们想查询某一个人的关系链 也是很方便的。

这里面有几个概念我们需要明确一下:
因为Neo4j是一个图数据库,可以认为它里面存储的都是图数据
图是由点(Vertex),边(Edge)和属性(Property)组成的

图里面的圆圈属于一个点、这个线属于边,圆圈中的这个姓名是属性。

点和边都可以设置属性,点也可以称作节点,边也可以称作关系,每个节点和关系都可以有一个或多个属性

在这里大家先对neo4j有一个整体的认识,下面我们开始学习neo4j中的具体使用

Neo4j的使用

那下面我们来看一下neo4j的常见操作

  1. 添加数据
  2. 查询数据
  3. 更新数据
  4. 建立索引
  5. 批量导入数据

添加数据

create:每次都创建新的点或边

创建两个节点

create (p1:Person {name:"zs"})
create (p2:Person {name:"ls"})

创建两个节点及它们之间的关系

create (p1:Person {name:"zs"}) -[:like]-> (p2:Person {name:"ls"})

注意:create会每次都创建新的节点或者关系

neo4j中除了有create命令,还要一个merge命令,这个命令在创建节点之前都会先查询一下,如果存在则不创建【这个merge命令就算是重复执行,也不会产生重复的结果】,所以在工作中建议使用merge

merge(p3:Person {name:"jack"})
merge(p4:Person {name:"tom"})
merge(p3) -[:like]->(p4)

注意:这个时候这三行命令需要在一个会话里面一起执行,否则merge里面无法识别p3和p4

在这里其实还有另外一种写法,如果节点已经存在了,我们只需要创建关系,还可以使用match来实现
所以在这里我们还需要引入一个match命令,使用match可以查询之前已有的节点或者关系等信息,这个命令还是很重要的,后面我们还会详细分析,在这里我们先使用match来查询已有的节点信息
在这里我们想让tom和jack也产生一个like关系
先查询tom和jack

match(a:Person {name:"tom"}),(b:Person {name:"jack"})
merge(a)-[:like]->(b)

这样就可以通过match查询之前已有的节点信息,然后再通过merge创建关系就行了,也不会额外产生重复的节点。

所以这两种方式都可以,按需选择即可。

查询数据

下面我们来查询一下neo4j中的数据
我们前面说过match可以进行查询,下面我们就来具体使用一下
这个match其实有点类似于mysql中的select
在这注意一下:match不能单独存在,我们前面在使用的时候match后面跟的也是有merge的
如果我们只想查询一些数据怎么办呢?

可以使用match+return,查看满足条件的数据并返回

match(p:Person {name:"tom"}) return p

那下面我们查询一些复杂一点的内容
首先初始化数据
注意:这里面这些创建点的操作和创建边的操作需要在一个会话里面一起执行

merge(a:User {name:"A"})
merge(b:User {name:"B"})
merge(c:User {name:"C"})
merge(x:User {name:"X"})
merge(y:User {name:"Y"})
merge(z:User {name:"Z"})
merge(a) -[:follow]-> (b)
merge(c) -[:follow]-> (b)
merge(a) -[:follow]-> (x)
merge(a) -[:follow]-> (y)
merge(c) -[:follow]-> (y)
merge(c) -[:follow]-> (z)

首先我们查询:
某个主播的粉丝信息

match (:User {name:"B"}) <-[:follow]- (n:User) return n

还有一种写法就是这样的

match (n:User) -[:follow]-> (:User {name:"B"}) return n

如果只想返回满足条件的粉丝的name的话,可以在n后面加上一个.name

match (n:User) -[:follow]-> (User {name:"B"}) return n.name

这个其实就是查询我要关注的主播的二度关系了

我–>主播B–>粉丝
这个时候 我 和 主播B的粉丝之间就属于二度关系了。

我们在这个项目中是想实现三度关系推荐
也就是当我要关注某个主播的时候,要给我推荐这个主播的粉丝又关注了哪些主播
所以说这个三度关系就是这样的

我–>主播B–>粉丝–>主播N
这个时候我和主播N之间就属于三度关系了。

那这个三度关系该如何查询呢?

match (a:User {name:"B"}) <-[:follow]- (b:User) -[:follow]-> (c:User)  return a.name as aname,b.name as bname,c.name as cname

结果是这样的,这里针对B的粉丝A和C关注了XYZ这三个主播,其中A和C都关注了Y

image

那在给我推荐的时候,是不是应该把B的粉丝关注比较多的主播推荐给我呢,在这里,理论上来说,Y最有可能是我喜欢的,Z和X的可能性就没那么大了

所以 在这里获取cname的时候,最好是做一下过滤,统计一下cname中相同主播出现的次数,然后按照倒序排序,最终取一个topn就可以了,这个topn里面的主播大概率是我也喜欢的主播

那这个该怎么实现呢?
其实match后面也支持count、order by 、limit等命令

match (a:User {name:"B"}) <-[:follow]- (b:User) -[:follow]-> (c:User)  return a.name as aname,c.name as cname,count(*) as sum order by sum desc limit 3

注意:这里相当于根据aname和cname进行分组,然后使用count统计每组的数据行数
这里的count(*) 和使用count(cname)是一样的效果。

image

这样就可以实现三度关系数据的查询了。
这里面其实还可以使用where加一些过滤条件。

注意,where需要放在return的前面。

match (a:User {name:"B"}) <-[:follow]- (b:User) -[:follow]-> (c:User) where c.name <> "X" return a.name as aname,c.name as cname,count(*) as sum order by sum desc limit 3

image

更新数据

更新数据这块其实总结一下有两种情况

  • 第一种是
    更新节点的属性, 使用match+set实现
  • 第二种是
    更新节点之间的关系(边),其实就是删除边,使用match+delete实现

首先看一下如何修改节点中的属性

match (a:User {name:"X"}) set a.age= 18

然后看一下如何删除关系

match (:User { name:"A"})-[r:follow]->(:User { name:"X"}) delete r

删除数据

match (n:User) delete n # 删除所有User节点,如果节点存在关系不能删除
match (n:User) detach delete n # 删除所有User节点,且删除存在的关系,级联删除
match (n) detach delete n # 删除整个数据库

建立索引

neo4j中的索引可以细分为两种

  1. 普通索引 CREATE INDEX ON :User(name)
    第一种是普通索引,使用create index 可以实现,指定给节点中的某个属性建立索引,具体建立索引的依据是后期我们在查询的时候是否需要在where中根据这个属性进行过滤,如果需要则建立索引,如果不需要则不建立索引。
  2. 唯一约束 CREATE CONSTRAINT ON (u:User) ASSERT u.id IS UNIQUE
    第二种索引称之为唯一约束,类似于mysql数据库中主键的唯一约束。
    使用CREATE CONSTRAINT可以实现
    CREATE CONSTRAINT ON (u:User) ASSERT u.id IS UNIQUE

那这两种在使用的时候具体该如何选择呢?

如果某个字段的值是唯一的,并且后期也需要根据这个字段进行过滤操作,那么就可以建立唯一约束,唯一约束的查询性能比索引更快

批量导入数据

针对项目开始的时候有一批海量数据需要导入,就不能使用我们前面讲的那些命令一条一条导入了,性能太差,我们需要有一个批量导入的方式来快速导入数据。
neo4j中批量导入数据有两种方式,一个是batch import 一个是load csv

  • 第一种是batch import,这种方式需要按照要求组装三个文件,导入性能比较快,但是比较麻烦
  • 第二种是load csv,只需要把数据组装到一个CSV文件即可,导入性能没有batch import快,但是使用起来方便

在这里我们考虑到易用性,由于我们的原始数据都在mysql中,可以通过mysql的命令直接把数据导出为一个文件,所以在这里我们使用load csv会更加方便。

注意:在load csv中使用了merge 或者match的时候,需要确认关键字段是否有索引,否则性能会很差。

例如:merge(a:User {name:“A”}),此时就需要提前对User中的name字段建立索引,否则在进行初始化的时候,数据量大了之后,初始化的性能会很差,因为merge在执行的时候会查询name等于A的数据在不在neo4j中,如果name字段没有建立索引,则会执行全表扫描。

那下面我们就先演示一下load csv的使用
先把neo4j中的数据清空了,然后重新启动一下,重新修改密码。

match (n) detach delete n

或者暴力删除

rm -rf data/

然后看一下准备的测试数据文件,follower_demo.log

fuid	uid
1001	1000
1001	1004
1001	1005
1001	2001
1002	1000
1002	1004
1002	2001
1003	1000
1003	1004
1006	1000
1006	1005
2002	1004
2002	1005
2002	2004
2003	1000
2003	1005
2003	2004

文件中有2列,fuid和uid fuid表示是关注者的uid,uid表示是被关注者(也就是主播)的uid。

需要把这个文件上传到NEO4J_HOME的import目录下才可以使用。

然后我们使用neo4j的shell命令行执行下面命令。

bin/cypher-shell -a bolt://bigdata01:7687 -u neo4j -p admin

首先针对关键字段建立索引

CREATE CONSTRAINT ON (user:User) ASSERT user.uid IS UNIQUE;

然后批量导入数据

USING PERIODIC COMMIT 1000
       LOAD CSV WITH HEADERS FROM 'file:///follower_demo.log' AS line FIELDTERMINATOR '\t'
       MERGE (viewer:User { uid: toString(line.fuid)})
       MERGE (anchor:User { uid: toString(line.uid)})
       MERGE (viewer)-[:follow]->(anchor);

在neo4j的web界面上也可以执行这种多行命令,需要添加:auto

解释:

  1. PERIODIC COMMIT 1000:每1000条提交一次,这个参数非常关键,如果在数据量很大的情况下内存。无法同时加载很多数据,所以需要批量提交事务,这样可以减小任务失败的风险,并且也可以提高数据导入的速度,当然这需要设置一个合适的数量。
  2. WITH HEADERS:是否使用列名,如果文件中有列名,则可以加这个参数,这样在读取数据的时候就会忽略第一行
  3. FIELDTERMINATOR ‘\t’:指定文件中的字段分隔符。

然后我们到页面上看一下导入的数据。

image

注意:此时我们会发现在页面中的圆圈中没有显示数据的具体内容,之前在用3.2版本的时候是没有这个问题的,现在使用新的3.5版本之后会发现页面显示的时候会出现这种问题,这个问题倒没什么影响,就是在页面中看起来不太方便而已。

通过测试发现:
如果我们在添加节点数据的时候,给节点指定一个name属性,那么name属性的值默认会显示在这个圆圈里面,如果不是name字段,则不显示。这个应该是新版本的一些特性。

可以尝试一下,将uid字段改为name字段

Java操作

<dependency>
    <groupId>org.neo4j.driver</groupId>
    <artifactId>neo4j-java-driver</artifactId>
    <version>4.1.1</version>
</dependency>
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.neo4j.driver.Record;
import org.neo4j.driver.Result;
import org.neo4j.driver.Session;

import java.util.List;

public class TestNeo4jClient {
    public static void main(String[] args) {
        //获取neo4j的连接
        String boltUrl = "bolt://bigdata01:7687";
        String username = "neo4j";
        String password = "admin";
        Driver driver = GraphDatabase.driver(boltUrl, AuthTokens.basic(username, password));
        //开启一个会话
        Session session = driver.session();
        session.run("merge(p:Person {name:\"jack\"})");
        Result result = session.run("match(p:Person) return p.name");
        List<Record> recordList = result.list();
        for (Record record : recordList) {
            System.out.println(record.asMap());
        }
        //关闭会话
        session.close();
        //关闭连接
        driver.close();
    }
}

参考

Neo4j 第三篇:Cypher查询入门
Neo4j 入门教程 - 使用 Cypher 删除关系

标签:name,数据库,主播,merge,User,Neo4j,neo4j,快速,match
From: https://www.cnblogs.com/strongmore/p/17381219.html

相关文章

  • R语言关联规则Apriori对抗肿瘤中药数据库知识发现研究
    肿瘤是近年来严重威胁人类的健康的疾病,据统计,目前大部分种类的肿瘤都呈现不同程度的上升趋势,中国因患肿瘤而死亡的人数约占全球肿瘤死亡总人数的1/4左右,人类正面临着肿瘤防治的新挑战。现代医学治疗肿瘤的手段和方式已经日臻完善,主要为手术配合放、化疗联合治疗。但传统西医治......
  • Access数据库文件HeroDB.MDB用什么工具可以打开呢?
    我们在架设GOM引擎的版本的时候,可能会发现,有的版本默认选择Access数据库,选择Access数据库的版本,我们可以在D:\mirserver\Mud2\DB这个路径找到一份HeroDB.MDB的文件,这是一个集成数据库,和HeroDB不一样DBC2000的数据库是有3个数据库文件的,分别是Magic.DB、Monster.DB、StdItems.DB,代表......
  • 关于MySQL数据库的外键作用及如何创建?
    一、外键的作用:外键的主要作用是保证数据的一致性和完整性,并且减少数据冗余。主要体现在以下两个方面:1、阻止执行从表插入新行,其外键值不是主表的主键值便阻止插入。从表修改外键值,新值不是主表的主键值便阻止修改。主表删除行,其主键值在从表里存在便阻止删除(要想删除,必须先删除......
  • ASNmap 使用ASN快速映射组织网络资产范围
    asnmap快速利用ASN信息映射组织网络范围的Go命令行工具和库。功能•安装•使用•运行asnmap•加入Discord功能ASN到CIDR查询ORG到CIDR查询DNS到CIDR查询IP到CIDR查询支持ASN/DNS/IP/ORG输入支持JSON/CSV/TEXT输出支持标准输入/输出安装为了成功安装asnmap,需......
  • 2023年06月数据库流行度最新排名
    点击查看最新数据库流行度最新排名(每月更新)2023年06月数据库流行度最新排名TOPDB顶级数据库索引是通过分析在谷歌上搜索数据库名称的频率来创建的一个数据库被搜索的次数越多,这个数据库就被认为越受欢迎。这是一个领先指标。原始数据来自谷歌Trends如果您相信集体智慧,那么TOP......
  • 基于JAVA的springboot篮球论坛系统,附源码+数据库+论文+PPT
    1、项目介绍考虑到实际生活中在篮球论坛方面的需要以及对该系统认真的分析,将系统权限按管理员和用户这两类涉及用户划分。(a)管理员;管理员使用本系统涉到的功能主要有:首页、个人中心、用户管理、篮球论坛、系统管理等功能。管理员用例图如图3-1所示。(b)用户;用户使用本系统......
  • vuepress快速安装笔记
    参考https://vuepress.vuejs.org/guide/getting-started.html#prerequisiteshttps://blog.llyth.cn/1065.html注意:应该是cd到新建项目文件夹的docs里,然后yarninstall。在项目文件夹里,执行yarndev启动运行项目,yarnbuild生产静态文件,结果与文件路径如下。waitRenderings......
  • Sentinel控制台监控数据持久化到MySQL数据库
    阅读文本大概需要3分钟。    根据官方wiki文档,Sentinel控制台的实时监控数据,默认仅存储5分钟以内的数据。如需持久化,需要定制实现相关接口。https://github.com/alibaba/Sentinel/wiki/在生产环境中使用-Sentinel给出了指导步骤:自行扩展实现MetricsRepository接口;注册成......
  • 时序列数据库选型
    时序列数据库武斗大会之什么是TSDB由于工作上的关系,最近看了一些关于时序列数据库的东西,当然,我所看的也都是以开源方案为主。趁着这股热劲还没退,希望能整理一些资料出来。如果正好你也有这方面的需求,那么希望这一系列的介绍能够帮助到你。1.什么是时序列数据库(Timeseriesdatabas......
  • SQLite数据库查看工具
    SQLite的官方网站[url]http://www.sqlite.org/[/url]SQLite的官方网址列了很多查看SQLite数据库的软件:[url]http://www.sqlite.org/cvstrac/wiki?p=ManagementTools[/url]这里推荐我使用过的几个,当然是免费的才行.1.SQLiteDatabaseBrowser[im......