• Neo4j应用


    CQL函数

    1. 字符串函数

    功能 描述
    UPPER 将所有字母改为大写
    LOWER 将所有字母改为小写
    SUBSTRING 将获取指定范围的子字符串
    REPLACE 替换一个字符串的子字符串
    match (p:Person) return ID(p),LOWER(p.character)
    

    2. 聚合函数

    聚集功能 描述
    COUNT 它返回由MATCH命令返回的行数
    MAX 它从MATCH命令返回的一组行返回最大值
    MIN 它返回由MATCH命令返回的一组行的最小值
    SUM 它返回由MATCH命令返回的所有行的求和
    AVG 它返回由MATCH命令返回的所有行的平均值

    示例:

    match (p:Person) return max(p.money)
    

    3. 关系函数

    功能 描述
    STARTNODE 用于知道关系的开始节点
    ENDNODE 用于知道关系的结束节点
    ID 用于知道关系的ID
    TYPE 用于知道字符串表示中的一个关系的TYPE

    示例:

    match p=(:Person {name:"范闲"})-[r:Couple]-(:Person) return ENDNODE(r)
    
    match p=(:Person {name:"范闲"})-[r:Couple]-(:Person) return type(r)
    

    4. 返回最短路径

    shortestPath函数

    示例:

    match p=shortestPath((person:Person {cid:1})-[*]-(person2:Person {cid:8})) return length(p),nodes(p)
    

    CQL多深度关系节点

    1. 使用with关键字

    查询三层级关系节点如下:with可以将前面查询结果作为后面查询条件

    match (na:Person)-[re]->(nb:Person) where na.name="范闲" WITH na,re,nb match (nb:Person)-
    [re2]->(nc:Person) return na,re,nb,re2,nc
    

    2. 直接拼接关系节点查询

    match data=(na:Person{name:"范闲"})-[re]->(nb:Person)-[re2]->(nc:Person) return data
    

    3. 使用深度运算符

    -[:TYPE*minHops..maxHops]-
    

    minHops代表最小深度,maxHops代表最大深度。

    match data=(na:Person{cid:1})-[*1..2]-(:Person) return data
    

    事务

    Neo4j支持ACID特性

    • 所有对Neo4j数据库的数据修改操作都必须封装在事务中
    • 默认的isolation level是READ_COMMITTED
    • 死锁保护已经内置到核心事务管理。
    • 除特殊说明,Neo4j的API操作都是线程安全的,Neo4j数据库的操作也就没有必要使用外部的同步方法。

    索引

    Neo4j支持在节点或关系的属性上建立索引,以提高应用程序的性能。可以在Match或where等运算符上使用这些索引改进SQL的执行。

    1. 单一索引
    CREATE INDEX ON :Label(property)
    

    示例:

    create index on:Person(name)
    
    1. 复合索引
    create index on:Person(age,gender)
    
    1. 全文索引

    常规索引只能对字符串进行精确匹配或前后缀索引,而全文索引可以匹配字符串任何位置的词语。

    使用db.index.fulltext.createNodeIndex和db.index.fulltext.createRelationshipIndex可以分别为节点和关系创建全文索引。在创建索引时,必须指定唯一的名称,用于查询和删除索引时要引用。

    call db.index.fulltext.createNodeIndex("索引名",[Label,Label],[属性,属性])
    

    示例:

    call db.index.fulltext.createNodeIndex("nameAndDescription",["Person"],["name",
    "description"])
    
    call db.index.fulltext.queryNodes("nameAndDescription", "范闲") YIELD node, score
    RETURN node.name, node.description, score
    
    1. 查看索引
    call db.indexes 或:schema
    
    1. 删除索引
    DROP INDEX ON :Person(name)
    DROP INDEX ON :Person(age, gender)
    call db.index.fulltext.drop("nameAndDescription")
    

    约束

    作用:唯一性约束用于避免重复记录

    1. 创建唯一性约束

    CREATE CONSTRAINT ON (变量:<label_name>) ASSERT 变量.<property_name> IS UNIQUE
    

    示例:

    create constraint on(person:Person) assert person.name is unique
    

    2. 删除唯一性约束

    drop constraint on (person:Person) assert person.name is unique
    

    3. 查看约束

    call db.constraints
    #或
    :schema
    

    Neo4j服务管理

    1. 备份和恢复

    1. 备份之前先停止服务
     bin/neo4j stop
    
    1. 备份命令
    bin/neo4j-admin dump --database=graph.db --to=/usr/local/qyn.dump
    

    然后启动服务,删除所有数据。然后在停止服务,准备恢复

    match (p)-[r]-() delete p,r
    
    1. 恢复命令
    bin/neo4j-admin load --from=/usr/local/qyn.dump --database=graph.db --force
    

    注意:运行数据备份可能会警告

    WARNING: Max 1024 open files allowed, minimum of 40000 recommended. See the Neo4j manual

    编辑这个文件:vim /etc/security/limits.conf,在文件最后面加上这段,修改最大打开文件限制,在重启服务器就行了。

    *        soft   nofile     65535
    *        hard   nofile     65535
    

    2. Neo4j调优

    2.1 调整neo4j配置文件

    # neo4j初始堆内存
    dbms.memory.heap.initial_size=512m
    # 最大堆内存
    dbms.memory.heap.max_size=512m
    # pagecache大小,官方建议设为:(总内存-dbms.memory.heap.max_size)/2
    dbms.memory.pagecache.size=10g
    

    2.2 数据预热

    match (n)
    optional match (n)-[r]->()
    return count(n.name)+count(r)
    
    1. 使用执行计划命令优化

    有如下两个命令:

    • Explain :解释机制,加入该关键字的Cypher语句可以预览执行的过程但是不实际执行
    • Profile:画像机制,查询中使用该关键字能够看到执行计划详细内容,还能看到查询的结果

    示例:

    profile match (p:Person {name:"范闲"}) return p
    

    需要关注指标:

    关注指标:

    estimated rows: 需要被扫描行数的预估值

    dbhits: 实际运行结果的命中绩效

    Neo4j 程序访问

    1. 数据库访问方式

    Neo4j访问有两种方式:

    • 嵌入式数据库
    • 服务器模式(通过REST的访问)

    嵌入式数据库

    嵌入式Neo4j数据库是性能的最佳选择,通过指定数据存储的路径以编程的方式访问。我们选择嵌入式数据库有如下的原因:

    • 使用java作为编程语言
    • 应用程序独立
    • 程序追求很高的性能

    服务器模式

    Neo4j Server是相互操作性、安全性和监控的最佳选择。实际上,REST接口允许所有现代平台和编程语言与它进行交互操作。此外,作为独立应用程序,他比嵌入式配置更安全(客户端的故障不会影响服务器),更易于监控。而且可以使用任意编程语言以REST的方式访问数据库。

    2. Java客户端访问

    2.1 嵌入式模式

    <dependency>
        <groupId>org.neo4j</groupId>
        <artifactId>neo4j</artifactId>
        <version>3.5.5</version>
    </dependency>
    

    新增数据

     public static void add(){
            GraphDatabaseService graphDb= new GraphDatabaseFactory().newEmbeddedDatabase(databaseDirectory);
            System.out.println("database load");
            Transaction tx = graphDb.beginTx();
            Node node = graphDb.createNode();
            node.setProperty("name","张三");
            node.setProperty("character","A");
            node.setProperty("money",2330);
            node.addLabel(() -> "Person");
            tx.success();
            tx.close();
            graphDb.shutdown();
        }
    

    查询数据

    public static void query(){
            GraphDatabaseService graphDb= new GraphDatabaseFactory().newEmbeddedDatabase(databaseDirectory);
            System.out.println("database load");
            String cql="match (a:Person) where a.money < $money return a";
            Map<String,Object> paramerters= new HashMap<>();
            paramerters.put("money",2500);
            Transaction tx=graphDb.beginTx();
            Result result = graphDb.execute(cql, paramerters);
            while (result.hasNext()){
                Map<String, Object> row = result.next();
                for (String key : result.columns()){
                    Node nd = (Node)row.get(key);
                    System.out.printf("%s = %s:%s%n",key,nd.getProperties("name"),nd.getProperties("money"));
                }
            }
            tx.success();
            tx.close();
            graphDb.shutdown();
        }
    

    2.2 服务器模式

    <dependency>
        <groupId>org.neo4j</groupId>
        <artifactId>neo4j-ogm-bolt-driver</artifactId>
        <version>3.2.10</version>
    </dependency>
    

    查询示例:

    public static void query(){
        Driver driver = GraphDatabase.driver("bolt://192.168.56.115:7687", AuthTokens.basic("neo4j", "123456"));
        Session session = driver.session();
        String cql="match (a:Person) where a.money > $money return a.name as name,a.money as money order by a.money";
        Result result = session.run(cql, Values.parameters("money", 400));
        while (result.hasNext()){
            Record record = result.next();
            System.out.println(record.get("name").asString()+"  "+record.get("money").asDouble());
        }
        session.close();
        driver.close();
    
    }
    

    SpringBoot 整合Neo4j

    1. 引入依赖
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-neo4j</artifactId>
    </dependency>
    
    1. 编写配置文件
    spring.data.neo4j.username=neo4j
    spring.data.neo4j.password=123456
    spring.data.neo4j.uri= bolt://192.168.56.115:7687
    
    1. 建立实体类
    @NodeEntity
    @Data
    public class Person {
        @Id
        @GeneratedValue
        private Long id;
    
        private Integer cid;
    
        private String name;
    
        private String character;
    
        private Double money;
    
        private Integer gender;
    
        private Integer age;
    
        private String description;
    
        @Relationship(type = "Friend",direction = Relationship.OUTGOING)
        private Set<Person> relationPersons;
    
    
    1. 编写数据持久层
    @Repository
    public interface PersonRepository extends Neo4jRepository<Person,Long> {
    
        @Query("match(p:Person) where p.money > {0} return p")
        List<Person> personList(Double money);
    
        @Query("match p=shortestPath((person:Person {name:{0}}) - [*1..2] - (person2:Person {name:{1}})) return p ")
        List<Person> shortestPath(String startName,String endName);
    }
    
    1. 测试
    Iterable<Person> all = personRepository.findAll();
    System.out.println(all);
    
  • 相关阅读:
    Atitit.atiJsBridge 新特性v7q329
    atitit.userService 用户系统设计 v6 q413
    atitit.userService 用户系统设计 v6 q413
    Atitit.获取某个服务 网络邻居列表 解决方案
    Hasse神舟笔记本卡logo解决,刷BIOS方法,教你修复神船
    Axure RP 8 注册码
    在本地硬盘安装WinPE系统,实现UEFI引导,摆脱U盘
    cmd实现批量文件的base64加密并双击加密文件后正常运行
    cmd的变量总结
    fiddler几种功能强大的用法
  • 原文地址:https://www.cnblogs.com/javammc/p/16513130.html
Copyright © 2020-2023  润新知