【neo4j】win/linux安装和使用+cypher+langchian+向量索引


neo4j

windows-community安装

官网安装教程
下载页面
提前装一下jdk17

解压和设置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 vs Http?

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。

pattern例子

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就会失败,报错是数据库受损。

先装下3.5.17对应的apoc

  • jar包放
  • conf文件添加apoc.export.file.enable=true
  • 查看安装成功:return apoc.version()
使用copy版本快速迁移(需要企业版neo4j)

官网数据迁移3.x到4.x
下一下4.4.36
4.4.36需要jdk11

迁移检查

  1. 彻底关闭dbms:neo4j.bat stop
  2. 备份:neo4j.conf文件,加密信息(<neo4j-home>/certificates/),dbms和data store文件。【感觉就是备份,conf、data、certificates三个文件夹】
    注意,data store文件需要其他方式备份,生成.dump文件:
$NEO4J_HOME/bin/neo4j-admin dump --to=$BACKUP_DESTINATION
  1. 构造新的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>

4.1load语法

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的时候会自动删除的。)
这里太麻烦,我直接删了索引。。嘿嘿。

版本4可以在线弄,用backup命令。但是仅限企业版。

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>

neo4j 5.22.0的dump
neo4j 5.22.0的load

  • 30
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis is a Java-based persistence framework that provides mapping between relational databases and Java objects. It helps simplify database access by handling database communication and SQL generation. On the other hand, Cypher is a query language specifically designed for querying graph databases, such as Neo4j. It allows you to express patterns and relationships in your data in a simple and intuitive way. If you're looking to use Cypher with MyBatis, it's important to note that MyBatis is primarily designed for relational databases, so it may not have built-in support for Cypher out of the box. However, you can still use MyBatis with Cypher by writing custom SQL queries that execute Cypher statements against a graph database. To do this, you can use the MyBatis `@SelectProvider` annotation along with a custom SQL provider class. In the SQL provider class, you can write the logic to generate the necessary Cypher queries and execute them against the graph database. Here's an example of how you can use MyBatis with Cypher: First, define your Cypher query in the SQL provider class: ``` public class CypherSqlProvider { public String getNodes() { return "MATCH (n) RETURN n"; } } ``` Next, use the `@SelectProvider` annotation in your MyBatis mapper interface: ``` @Mapper public interface NodeMapper { @SelectProvider(type = CypherSqlProvider.class, method = "getNodes") List<Node> getNodes(); } ``` In this example, the `getNodes` method in the `CypherSqlProvider` class generates a Cypher query that matches all nodes in the graph database and returns them. The `@SelectProvider` annotation in the `NodeMapper` interface associates the method with the SQL provider class. Please note that this is just a basic example, and depending on your specific use case, you may need to modify it accordingly. I hope this answers your question. Let me know if you have any further queries!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值