文章目录
neo4j
windows-community安装
解压和设置NEO4J_HOME就可以了
set NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
set NEO4J_ACCEPT_LICENSE_AGREEMENT=eval
windows-desktop安装和新建database
前置:安装前先删干净
https://blog.csdn.net/qq_40808877/article/details/133968674
卸载不彻底
C:\Users\xxxxxx.Neo4jDesktop
C:\Users\xxxxxx.Neo4jDesktop\persist
都删了
Desktop版官网安装教程
官网下载的时候会有一个activation key
然后添加一个database
设置下数据库名和密码,我这里设置的数据库是test,密码是rootroot。
建好就可以start了。start会慢一点。
启动好后可以打开浏览页面。直接open
http://localhost:7474是http协议的url
bolt://localhost:7687是bolt协议。
进入http://localhost:7474后输入用户密码,用户名是neo4j,密码是刚刚设置的数据库密码。
linux-community安装(命令行)和新建database
主要问题在于我在linux服务器上没有管理员权限,安装有点别扭。
官网安装教程
具体流程:
先在官网下载对应的文件(linux版)
下载链接
我下的文件版本是neo4j-community-5.21.2,解压一下:tar zxf neo4j-community-5.21.2
设置下环境变量,把解压后的neo4j-community-5.21.2/bin放到环境变量的path里。
neo4j的启动和停止
启动:neo4j start
console启动:neo4j console
查看运行状态:neo4j status
停止:neo4j stop
csdn上新建database的做法
stackoverflow上新建database的做法
两者是一样的,很暴力,但是好像只能这样。。
具体做法:
安装目录里找到conf/neo4j.conf
中的dbms.active_database=neo4j
并修改neo4j为新建的数据库名称,然后重启neo4j。
如果找不到,就自己添加。就可以新建database。
可能遇到的问题
遇到问题的时候命令里添加--verbose
查看下报错。
Q1 端口被占用?
报错neo4j aused by: io.netty.channel.unix.Errors$NativeIoException: bind(..) failed: Address already in use
解决办法:netstat -tuln | grep <端口号>
或者lsof -i:<端口号>
根据报错查看占用的端口,然后杀掉占端口的进程
Q2 转发远程服务器端口号本地端口,从而在本地查看browser
报错WebSocket connection failure. Due to security constraints in your web browser, the reason for the failure is not available to this Neo4j Driver
参考做法(失败)
上述做法是在conf配置里取消一行内容的注释,但是我这版的conf根本没有这行内容。硬添加会报错。
参考做法(成功)
远程服务器端口的7474(http)和(7687)端口都要转发。
尝试了下,需要端口原封不动的转发(即,不能把7474端口转发到7475)。
错误:ssh -R 7475:localhost:7474 -N <本地计算机账号名>@<本地计算机ip>
正确:ssh -R 7474:localhost:7474 -N <本地计算机账号名>@<本地计算机ip>
Q3 输错密码太多次超时
报错Security.AuthenticationRateLimit: The client has provided incorrect authentication details too many times in a row.
https://github.com/neo4j/docker-neo4j/issues/385
只能多等等了。。。等时间过了再回来试试。
python使用
Bolt 协议是一种二进制协议,性能比Http更好。数据多并发强的时候Bolt。 数据少、性能要求不高、查询简单用Http。
参考
照上面参考的使用就可以了,windows和linux两版的连接都没有问题。
密码都设置了rootroot。
neo4j用的cypher查询语言
neo4j包
连接driver:
from neo4j import GraphDatabase
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "rootroot")) # neo4j是用户名 rootroot是密码,根据具体情况填写
增删改查
官网增删改查介绍
注意所有的参数名不能以单个的_
结尾,避免和关键词配置参数冲突。
参数database_
如果没有提供,就默认为用户的home database,即browser登录后默认的数据库。
增加CREATE
summary = driver.execute_query(
"CREATE (:Person {name: $name})",
name="Alice",
database_="neo4j",
).summary
print("Created {nodes_created} nodes in {time} ms.".format(
nodes_created=summary.counters.nodes_created,
time=summary.result_available_after
))
删除DETACH DELETE
records, summary, keys = driver.execute_query("""
MATCH (p:Person {name: $name})
DETACH DELETE p
""", name="Alice",
database_="neo4j",
)
print(f"Query counters: {summary.counters}.")
修改SET
records, summary, keys = driver.execute_query("""
MATCH (p:Person {name: $name})
SET p.age = $age
""", name="Alice", age=42,
database_="neo4j",
)
print(f"Query counters: {summary.counters}.")
# 给alice和bob之间添加关系
records, summary, keys = driver.execute_query("""
MATCH (alice:Person {name: $name})
MATCH (bob:Person {name: $friend})
CREATE (alice)-[:KNOWS]->(bob)
""", name="Alice", friend="Bob",
database_="neo4j",
)
print(f"Query counters: {summary.counters}.")
查询
driver.execute_query(
"MERGE (:Person {name: $name})",
name="Alice", age=42,
database_="neo4j",
)
可能报错
传参?$
不能传部分参数
官网说明
属性名、关系名、类别都不能传参。所以下面三个都是错的。
MATCH (n) WHERE n.$param = 'something'
MATCH (n)-[:$param]→(m)
MATCH (n:$param)
传参主要是用在属性值、表达式上。
transaction
Session.execute_read()
读
Session.execute_write()
写
但是个人感觉,之前java+sql的时候大家也更喜欢把复杂操作留在java上。
所以还是直接用普通的queries更方便?
官网链接
但是直接transacation,复杂操作留在cypher这边会更快。。。数据量大就transaction吧。
py2neo
cypher语言
官网cypher手册
DBMS是数据库管理系统,客户端client应用连接DBMS,打开一个session,访问DBMS中的任意图graph。
通常一个数据库database只有一个图。
neo4j有内置的两个数据库,名称为system和neo4j。system数据库不要去动,存的是系统数据。
一次transaction只能访问一个database。
queries
一个neo4j的graph里有三个核心实体:nodes, relationships, and paths.
nodes
nodes含义和实体差不多,查询时由()
包起来。例子:
MATCH (n:Person {name:'Anna'})
RETURN n.born AS birthYear
上例的Person是实体的label,实际上每个实体可以有多个label,感觉和类别差不多。name是属性。即找name为Anna的Person类的实体。n是查询的变量。
relationships
relationships相当于是个三元组(start_node, relation_type, end_node),由-->
表示关系方向,即start_node - relation -> end_node
。具体的relation_type由[]
包围。
MATCH (:Person {name: 'Anna'})-[r:KNOWS WHERE r.since < 2020]->(friend:Person)
RETURN count(r) As numberOfFriends
上例,同理KNOWS是关系的类别,属性要求在WHERE后面。
paths
注意路径的连接是start_node - relation信息 - end_node
Quantified relationships例子
MATCH (n:Person {name: 'Anna'})-[:KNOWS]-{1,5}(friend:Person WHERE n.born < friend.born)
RETURN DISTINCT friend.name AS olderConnections
上例的意思是从start_node出发,只走关系类型为KNOWS的变,找到在1-5步内可达的上述限定的friend。
MATCH p=shortestPath((:Person {name: 'Anna'})-[:KNOWS*1..10]-(:Person {nationality: 'Canadian'}))
RETURN p
找最短路,并且路径长度在10hops内。
基本使用
记得先构建一个新数据库来试。
构建官网movies数据库的cypher代码
直接把cypher代码复制到browser里执行就好了
和langchain结合
官网说明
注意 langchain调用neo4j需要安装APOC插件。
官网安装教程
注意apoc_full和apoc_core不可兼得,apoc_full更完整。
插件的jar包
放在安装目录的plugins下,并在neo4j.conf里添加一行dbms.security.procedures.unrestricted=apoc.*,algo.*
检查是否安装成功的cypher命令RETURN apoc.version()
向量索引内容
neo4j版本5以上,部分函数要求5.18以上
官网介绍
csdn给出的安装方法
neo4j有两种索引方式,一种是索引文本(整个三元组full-text,即Relationship),一种是向量化Node或者Relation。
full-text向量化
貌似不能向量化整个三元组?
官网向量化例子
同理,添加关系的embedding函数是db.create.setRelationshipVectorProperty
官网代码1
官网代码2
def add_vectors():
model = BertEmb() # 自定义的 model.embed_query(str) 返回一个list 装的是embedding
# step1: get embeddings
code = "MATCH (e) RETURN e.id as id, e.name as name"
entity_names = driver.execute_query(code)
entity_list = []
print(f'Begin generate embeddings ...')
for idx, record in enumerate(tqdm(entity_names.records)):
id = record.get('id')
name = record.get('name')
curr_emb = {
'id': id,
'name': name,
'embedding': model.embed_query(name)
}
entity_list.append(curr_emb)
# step2: set NodeVectorProperty
print(f'Begin adding embeddings as property...')
batch = 100
total_num = len(entity_names.records)
pbar = tqdm(total=total_num)
for step in range(0, total_num, batch):
range_start = step
range_end = min(total_num, range_start+batch)
batch_entities = entity_list[range_start:range_end]
create_embeddings_code = """
UNWIND $entities as entity
MATCH (e:Entity {id:entity.id})
CALL db.create.setNodeVectorProperty(e, 'embedding', entity.embedding)
"""
driver.execute_query(create_embeddings_code, entities=batch_entities)
pbar.update(range_end-range_start)
pbar.close()
# step3: add index
print(f'Begin adding index...')
create_index_code = """
CREATE VECTOR INDEX entity_embeddings IF NOT EXISTS
FOR (e:Entity)
ON e.embedding
OPTIONS {indexConfig: {
`vector.dimensions`: 768,
`vector.similarity_function`: 'cosine'
}
}
"""
driver.execute_query(create_index_code)
如何删除索引?DROP INDEX entity_embeddings IF EXISTS
快速导入大量数据
参考量级
neo4j-admin database import
不同版本的neo4j之间数据迁移(大坑)
例子:版本3.5.17->5.22.0
支持迁移的顺序【很重要】
不按顺序迁移会报错
可以看到如果从3.5迁移到5.22,如果用neo4j-admin去迁移,要切换好多个版本。切换还好,重点是很多版本已经下不到了。。。
如果不按顺序来,实测是显示非最新状态,数据会有损失。比如我从3.5.17强行dump+load给了4.4.36,4.4.36能打开数据库查看,但是显示非最新状态。然后在dump+load给5.22.0就会失败,报错是数据库受损。
- jar包放
- conf文件添加
apoc.export.file.enable=true
- 查看安装成功:
return apoc.version()
使用copy版本快速迁移(需要企业版neo4j)
官网数据迁移3.x到4.x
下一下4.4.36
4.4.36需要jdk11
- 彻底关闭dbms:
neo4j.bat stop
- 备份:
neo4j.conf
文件,加密信息(<neo4j-home>/certificates/
),dbms和data store文件。【感觉就是备份,conf、data、certificates三个文件夹】
注意,data store文件需要其他方式备份,生成.dump
文件:
$NEO4J_HOME/bin/neo4j-admin dump --to=$BACKUP_DESTINATION
- 构造新的
neo4j.conf
:手动修改。。根据旧conf改新conf
因为数据比较大,加一个log查看迁移情况:
在conf里把dbms.directories.logs
那行取消注释。
注意免费版没有copy权限。。。 按照官网的教程是需要copy命令的。
后面看了其他教程,可以用load(包括官方的4.x迁到5.x也是用load)。这里我从3.x迁到4.x试了下也可以load。即使用4.x版本的neo4j-admin直接load dump文件到数据库:
neo4j-admin load --from=...dump --database=<database_name>
但是数据是非最新状态。后面没再尝试了
使用load缓慢迁移
找到各个历史版本
3.5.17->5.22.0
先从3.5.17迁移到4.4.36:
4.x需要jdk11
3.5.17迁移到4.0.12:
生成数据库的dumps文件:
neo4j-admin dump --to=$BACKUP_DESTINATION
注意$BACKUP_DESTINATION的文件名应该是<db_name>.dump
。<db_name>是要迁移的数据库的名字。
需要在4.0版本的neo4j的conf里添加如下两行(neo4j2是我的数据库名)
dbms.allow_upgrade=true
dbms.default_database=neo4j2
4.0版本的neo4j-admin执行:
neo4j-admin load --from=$BACKUP_DESTINATION/<db_name>.dump –database=<db_name> --force
迁移完毕。但是不知道为什么chrome打开是空白,edge打开是正常的。
4.0.12迁移到4.1.13:
同理conf设置+dump+load。conf不变。
4.0dump语法有变化,显式指明database的名字。path要以.dump
结尾。
neo4j-admin dump --database=<database> --to=<destination-path>
neo4j-admin load [--verbose] --from=<archive-path> --database=<database>
之后同理。
4.3的dump语法有变化,增加了参数:--expand-commands
。但是添加这个参数我这边会报错。
4.4.36迁移到5.22.0:
官网4.4->5.x
注意此时是dump+load+migrate。
并且如果版本4有索引,需要修改一下。。因为版本5中,把版本4的BTREE indexes 换成了 RANGE, POINT, and TEXT indexes。
所以需要创建可替代的index,但是不能删掉已有的index(因为在4里会报错,迁移到5的时候会自动删除的。)
这里太麻烦,我直接删了索引。。嘿嘿。
neo4j-admin backup --database=<databasename> --backup-dir=/migration-backups --include-metadata=all
版本4也可以离线,用dump。社区版可用。。做法和前面一样。
注意版本5中conf有变化:(neo4j2是我的数据库名称)
initial.dbms.default_database=neo4j2
此外不需要设置upgrade,因为后续会有migrate。
注意.dump所在的目录
必须只有dump,没有其他文件。neo4j2是我数据库的名字。
neo4j-admin database load --from-path=<.dump所在的目录> neo4j2 --overwrite-destination=true
neo4j-admin database migrate <databasename>