Neo4j(三) - 使用Java操作Neo4j详解

news2025/7/20 21:41:00

文章目录

  • 前言
  • 一、创建项目
  • 二、导入依赖
  • 三、节点和关系数据打印
  • 四、创建节点与关系
  • 五、查询数据方法
  • 六、更新数据方法
  • 七、删除节点与关系方法
  • 八、合并数据方法
  • 九、完整代码
    • 1. 完整代码
    • 2. 项目下载


前言

本文介绍通过 Java 操作 Neo4j 图数据库的完整流程。主要涵盖开发环境搭建、依赖导入、节点与关系的创建、查询、更新、删除及合并等操作,旨在为读者提供从入门到实践的全流程指导。


一、创建项目

在开始使用 Java 操作 Redis 之前,需先搭建开发环境。本章节以 IDEA 为开发工具,演示如何创建一个基于 Maven 的 Java 项目。通过 IDEA 的项目向导,依次选择 Java 项目类型、配置 Maven 管理依赖、指定 JDK 版本,快速生成标准的项目结构,为后续引入 Neo4j 依赖和编写代码做好准备。

打开IDEA,点击文件-->新建-->项目

在这里插入图片描述

如下图所示,选择Java-->输入项目名-->选择位置-->选择Maven-->选择JDK-->点击创建

在这里插入图片描述


二、导入依赖

介绍 Maven 依赖管理工具的作用,通过在 pom.xml 文件中添加 Neo4j 驱动依赖(neo4j-java-driver),并刷新 Maven 下载相关 Jar 包。此步骤是连接和操作 Neo4j 数据库的必要前提,确保项目能正确调用 Neo4j 的 Java 接口。

pom.xml文件中添加如下依赖配置。

    <dependencies>
        <dependency>
            <groupId>org.neo4j.driver</groupId>
            <artifactId>neo4j-java-driver</artifactId>
            <version>4.2.3</version>
        </dependency>
    </dependencies>

添加依赖后如下图所示,点击右上角的刷新图标下载配置Neo4j的Java驱动依赖包。

在这里插入图片描述


三、节点和关系数据打印

定义两个工具方法 printNodeData 和 printRelationshipData,分别用于打印节点和关系的详细信息(如 ID、标签、属性、起始节点、关系类型等)。这些方法在后续操作中用于验证数据的正确性,帮助开发者直观查看数据库中的节点和关系结构。

    public static void printNodeData(String val, Record record) {
        System.out.println("identity:" + record.get(val).asNode().id());
        System.out.println("labels:" + record.get(val).asNode().labels());
        System.out.println("properties:" + record.get(val).asNode().asMap());
    }

    public static void printRelationshipData(String val, Record record) {
        System.out.println("identity:" + record.get(val).asRelationship().id());
        System.out.println("start:" + record.get(val).asRelationship().startNodeId());
        System.out.println("end:" + record.get(val).asRelationship().endNodeId());
        System.out.println("type:" + record.get(val).asRelationship().type());
        System.out.println("properties:" + record.get(val).asRelationship().asMap());
    }

四、创建节点与关系

提供多个示例演示如何通过 Cypher 语句创建节点和关系:

  • 创建单个节点(含属性);
  • 创建多个节点并建立单向 / 双向关系;
  • 使用已存在节点创建关系。
  • 通过 session.run() 执行 Cypher 语句,并输出操作结果,展示 Neo4j 图数据模型的灵活性。
    public static void createOperation(Session session) {
        // 示例 1:创建一个简单的节点
        Result run1 = session.run("CREATE (a:Person {name: 'Alice', age: 30})");
        System.out.println(run1.consume());
        // 示例 2:创建两个节点并建立关系
        Result run2 = session.run("CREATE (a:Person {name: 'Alice'}) " + "CREATE (b:Person {name: 'Bob'}) " + "CREATE (a)-[r:FRIENDS_WITH {since: 2020}]->(b)");
        System.out.println(run2.consume());
        // 示例 3:在一个命令中创建节点和关系
        Result run3 = session.run("CREATE (a:Person {name: 'Alice'})-[:WORKS_AT]->(b:Company {name: 'Tech Corp'})");
        System.out.println(run3.consume());
        // 示例 4:使用已存在的节点创建关系
        Result run4 = session.run("MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) " + "CREATE (a)-[r:COLLEAGUE_OF {department: 'Engineering'}]->(b)");
        System.out.println(run4.consume());
        // 示例 5:创建双向关系
        Result run5 = session.run("MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) " + "CREATE (a)-[:KNOWS]->(b) " + "CREATE (b)-[:KNOWS]->(a)");
        System.out.println(run5.consume());
    }

五、查询数据方法

详细列举多种查询场景,涵盖基础查询到复杂过滤:

  • 查询所有节点、特定属性节点;
  • 关联查询节点及其关系;
  • 使用 WHERE 过滤条件、模糊匹配关系类型;
  • 限制结果数量(LIMIT)和分页(SKIP)。
  • 通过遍历 Result 对象并调用打印方法,展示查询结果的解析和呈现方式。
    private static void matchOperation(Session session) {
        // 示例 1:查询所有 Person 节点
        System.out.println("查询所有 Person 节点:");
        Result result1 = session.run("MATCH (p:Person) RETURN p");
        while (result1.hasNext()) {
            Record record = result1.next();
            System.out.println("=========================");
            printNodeData("p", record);
        }

        // 示例 2:查询具有特定属性的节点
        System.out.println("查询具有特定属性的节点:");
        Result result2 = session.run("MATCH (p:Person {name: 'Alice'}) RETURN p");
        while (result2.hasNext()) {
            Record record = result2.next();
            System.out.println("=========================");
            printNodeData("p", record);
        }

        // 示例 3:查询节点和其关系
        System.out.println("查询节点和其关系:");
        Result result3 = session.run("MATCH (a:Person {name: 'Alice'})-[r:KNOWS]->(b:Person) RETURN a, r, b");
        while (result3.hasNext()) {
            Record record = result3.next();
            System.out.println("===========a===========");
            printNodeData("a", record);
            System.out.println("===========r===========");
            printRelationshipData("r", record);
            System.out.println("===========b===========");
            printNodeData("b", record);
        }

        // 示例 4:仅返回某些字段或属性
        System.out.println("仅返回某些字段或属性:");
        Result result4 = session.run("MATCH (p:Person) RETURN p.name, p.age");
        while (result4.hasNext()) {
            Record record = result4.next();
            System.out.println(record.get("p.name") + " " + record.get("p.age"));
        }

        // 示例 5:使用 WHERE 过滤年龄大于 25 的人
        System.out.println("使用 WHERE 过滤年龄大于 25 的人:");
        Result result5 = session.run("MATCH (p:Person) WHERE p.age > 25 RETURN p.name, p.age");
        while (result5.hasNext()) {
            Record record = result5.next();
            System.out.println(record.get("p.name") + " " + record.get("p.age"));
        }

        // 示例 6:查找双向关系(比如互为好友)
        System.out.println("查找双向关系(比如互为好友):");
        Result result6 = session.run("MATCH (a:Person {name: 'Alice'})-[r1:KNOWS]->(b:Person {name: 'Bob'}) " + "MATCH (b)-[r2:KNOWS]->(a) RETURN a, r1, b, r2");
        while (result6.hasNext()) {
            Record record = result6.next();
            System.out.println("===========a===========");
            printNodeData("a", record);
            System.out.println("===========r1===========");
            printRelationshipData("r1", record);
            System.out.println("===========b===========");
            printNodeData("b", record);
            System.out.println("===========r2===========");
            printRelationshipData("r2", record);
        }

        // 示例 7:模糊匹配多个关系类型
        System.out.println("模糊匹配多个关系类型:");
        Result result7 = session.run("MATCH (a:Person {name: 'Alice'})-[:KNOWS|WORKS_WITH]->(b) RETURN b.name");
        while (result7.hasNext()) {
            Record record = result7.next();
            System.out.println(record.get("b.name"));
        }

        // 示例 8:限制返回数量
        System.out.println("限制返回数量:");
        Result result8 = session.run("MATCH (p:Person) RETURN p.name LIMIT 3");
        while (result8.hasNext()) {
            Record record = result8.next();
            System.out.println(record.get("p.name"));
        }
        // 跳过 1 个查询结果并最多返回 3 个 Person 的名字。
        System.out.println("跳过 1 个查询结果并最多返回 3 个 Person 的名字:");
        Result result9 = session.run("MATCH (p:Person) RETURN p.name SKIP 1 LIMIT 3");
        while (result9.hasNext()) {
            Record record = result9.next();
            System.out.println(record.get("p.name"));
        }
    }

六、更新数据方法

介绍节点和关系的更新操作:

  • 修改节点属性、添加新属性、批量设置属性;
  • 删除节点属性或标签;
  • 更新关系属性(如修改关系的时间戳)。

通过 SET 和 REMOVE 关键字演示数据更新逻辑,确保开发者掌握动态维护图数据的能力。

    private static void updateOperation(Session session) {
        // 示例 1:更新节点的属性
        System.out.println("更新节点的属性:");
        Result result1 = session.run("MATCH (n:Person {name: 'Alice'}) SET n.age = 31 RETURN n");
        while (result1.hasNext()) {
            Record record = result1.next();
            System.out.println("=========================");
            printNodeData("n", record);
        }

        // 示例 2:添加新的属性
        System.out.println("添加新的属性:");
        Result result2 = session.run("MATCH (n:Person {name: 'Bob'}) SET n.email = 'bob@example.com' RETURN n");
        while (result2.hasNext()) {
            Record record = result2.next();
            System.out.println("=========================");
            printNodeData("n", record);
        }

        // 示例 3:一次性设置多个属性
        System.out.println("一次性设置多个属性:");
        Result result3 = session.run("MATCH (n:Person {name: 'Bob'}) SET n.age = 45, n.city = 'Shanghai', n.job = 'Engineer' RETURN n");
        while (result3.hasNext()) {
            Record record = result3.next();
            System.out.println("=========================");
            printNodeData("n", record);
        }

        // 示例 4:删除节点的某个属性
        System.out.println("删除节点的某个属性:");
        Result result4 = session.run("MATCH (n:Person {name: 'Alice'}) REMOVE n.age RETURN n");
        while (result4.hasNext()) {
            Record record = result4.next();
            System.out.println("=========================");
            printNodeData("n", record);
        }

        // 示例 5:删除节点的标签
        System.out.println("删除节点的标签:");
        Result result5 = session.run("MATCH (n:Person {name: 'Bob'}) REMOVE n:Person SET n:User RETURN n");
        while (result5.hasNext()) {
            Record record = result5.next();
            System.out.println("=========================");
            printNodeData("n", record);
        }

        // 示例 6:更新关系属性
        System.out.println("更新关系属性:");
        Result result6 = session.run("MATCH (:Person {name: 'Alice'})-[r:KNOWS]->(:User {name: 'Bob'}) SET r.since = 2021 RETURN r");
        while (result6.hasNext()) {
            Record record = result6.next();
            System.out.println("=========================");
            printRelationshipData("r", record);
        }
    }

七、删除节点与关系方法

演示不同维度的删除操作:

  • 删除特定节点间的关系;
  • 删除指定类型的所有关系;
  • 级联删除节点及其关联关系(DETACH DELETE);
  • 清除孤立节点或整个图数据库。

强调删除操作的谨慎性,尤其是清空数据的场景需特别注意。

    private static void deleteOperation(Session session) {
        // 示例 1:删除两个特定节点之间的关系
        System.out.println("删除两个特定节点之间的关系:");
        session.run("MATCH (a:Person {name: 'Alice'})-[r:KNOWS]->(b:Person {name: 'Bob'}) DELETE r");

        // 示例 2:删除特定类型的关系
        System.out.println("删除特定类型的关系:");
        session.run("MATCH ()-[r:KNOWS]->() DELETE r");

        // 示例 3:删除某个特定节点(先删除关系)
        System.out.println("删除某个特定节点(先删除关系):");
        session.run("MATCH (n:Person {name: 'Alice'}) DETACH DELETE n");

        // 示例 4:删除没有关系的孤立节点
        System.out.println("删除没有关系的孤立节点:");
        session.run("MATCH (n) WHERE NOT EXISTS((n)--()) DELETE n");

        // 示例 5:删除所有节点和关系(清空整个图数据库)
        System.out.println("删除所有节点和关系(清空整个图数据库):");
        session.run("MATCH (n) DETACH DELETE n");
    }

八、合并数据方法

讲解 MERGE 语句的使用场景,确保节点或关系存在(若不存在则创建,存在则匹配):

  • 确保单个节点存在并设置属性;
  • 区分创建与更新操作(ON CREATE/ON MATCH);
  • 合并带属性的关系,避免重复数据。

通过 MERGE 实现数据的幂等性操作,适用于需要保证数据唯一性的场景。

    private static void mergeOperation(Session session) {
        // 示例 1:确保某节点存在(若不存在则创建)
        System.out.println("确保某节点存在(若不存在则创建):");
        Result result1 = session.run("MERGE (p:Person {name: 'Alice'}) RETURN p");
        while (result1.hasNext()) {
            Record record = result1.next();
            System.out.println("=========================");
            printNodeData("p", record);
        }

        // 示例 2:确保节点存在,并设置额外属性
        System.out.println("确保节点存在,并设置额外属性:");
        Result result2 = session.run("MERGE (p:Person {name: 'Bob'}) SET p.age = 30 RETURN p");
        while (result2.hasNext()) {
            Record record = result2.next();
            System.out.println("=========================");
            printNodeData("p", record);
        }

        // 示例 3:使用 ON CREATE 和 ON MATCH 区分创建与更新操作
        System.out.println("使用 ON CREATE 和 ON MATCH 区分创建与更新操作:");
        Result result3 = session.run("MERGE (p:Person {name: 'Charlie'}) " + "ON CREATE SET p.created = datetime() " + "ON MATCH SET p.lastSeen = datetime() " + "RETURN p");
        while (result3.hasNext()) {
            Record record = result3.next();
            System.out.println("=========================");
            printNodeData("p", record);
        }

        // 示例 4:合并关系(确保两个节点之间有某种关系)
        System.out.println("合并关系(确保两个节点之间有某种关系):");
        Result result4 = session.run("MERGE (a:Person {name: 'Alice'}) " + "MERGE (b:Person {name: 'Bob'}) " + "MERGE (a)-[r:FRIENDS_WITH]->(b) " + "RETURN a, r, b");
        while (result4.hasNext()) {
            Record record = result4.next();
            System.out.println("===========a===========");
            printNodeData("a", record);
        }

        // 示例 5:合并带属性的关系
        System.out.println("合并带属性的关系:");
        Result result5 = session.run("MERGE (a:Person {name: 'Alice'}) " + "MERGE (b:Person {name: 'Bob'}) " + "MERGE (a)-[r:WORKS_WITH {since: 2022}]->(b) " + "RETURN r");
        while (result5.hasNext()) {
            Record record = result5.next();
            System.out.println("=========================");
            printRelationshipData("r", record);
        }
    }

九、完整代码

1. 完整代码

提供包含主函数的完整 Java 代码,整合前文所有操作逻辑。

package org.example;

import org.neo4j.driver.*;

public class Main {
    public static void main(String[] args) {
        // 创建Neo4jDriver实例
        Driver driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j", "123456"));
        // 创建Session实例
        Session session = driver.session();

        createOperation(session);
        matchOperation(session);
        updateOperation(session);
        deleteOperation(session);
        mergeOperation(session);

        // 关闭Session实例
        session.close();
        // 关闭Neo4jDriver实例
        driver.close();
    }

    public static void printNodeData(String val, Record record) {
        System.out.println("identity:" + record.get(val).asNode().id());
        System.out.println("labels:" + record.get(val).asNode().labels());
        System.out.println("properties:" + record.get(val).asNode().asMap());
    }

    public static void printRelationshipData(String val, Record record) {
        System.out.println("identity:" + record.get(val).asRelationship().id());
        System.out.println("start:" + record.get(val).asRelationship().startNodeId());
        System.out.println("end:" + record.get(val).asRelationship().endNodeId());
        System.out.println("type:" + record.get(val).asRelationship().type());
        System.out.println("properties:" + record.get(val).asRelationship().asMap());
    }

    public static void createOperation(Session session) {
        // 示例 1:创建一个简单的节点
        Result run1 = session.run("CREATE (a:Person {name: 'Alice', age: 30})");
        System.out.println(run1.consume());
        // 示例 2:创建两个节点并建立关系
        Result run2 = session.run("CREATE (a:Person {name: 'Alice'}) " + "CREATE (b:Person {name: 'Bob'}) " + "CREATE (a)-[r:FRIENDS_WITH {since: 2020}]->(b)");
        System.out.println(run2.consume());
        // 示例 3:在一个命令中创建节点和关系
        Result run3 = session.run("CREATE (a:Person {name: 'Alice'})-[:WORKS_AT]->(b:Company {name: 'Tech Corp'})");
        System.out.println(run3.consume());
        // 示例 4:使用已存在的节点创建关系
        Result run4 = session.run("MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) " + "CREATE (a)-[r:COLLEAGUE_OF {department: 'Engineering'}]->(b)");
        System.out.println(run4.consume());
        // 示例 5:创建双向关系
        Result run5 = session.run("MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}) " + "CREATE (a)-[:KNOWS]->(b) " + "CREATE (b)-[:KNOWS]->(a)");
        System.out.println(run5.consume());
    }

    // 2. 查询数据
    private static void matchOperation(Session session) {
        // 示例 1:查询所有 Person 节点
        System.out.println("查询所有 Person 节点:");
        Result result1 = session.run("MATCH (p:Person) RETURN p");
        while (result1.hasNext()) {
            Record record = result1.next();
            System.out.println("=========================");
            printNodeData("p", record);
        }

        // 示例 2:查询具有特定属性的节点
        System.out.println("查询具有特定属性的节点:");
        Result result2 = session.run("MATCH (p:Person {name: 'Alice'}) RETURN p");
        while (result2.hasNext()) {
            Record record = result2.next();
            System.out.println("=========================");
            printNodeData("p", record);
        }

        // 示例 3:查询节点和其关系
        System.out.println("查询节点和其关系:");
        Result result3 = session.run("MATCH (a:Person {name: 'Alice'})-[r:KNOWS]->(b:Person) RETURN a, r, b");
        while (result3.hasNext()) {
            Record record = result3.next();
            System.out.println("===========a===========");
            printNodeData("a", record);
            System.out.println("===========r===========");
            printRelationshipData("r", record);
            System.out.println("===========b===========");
            printNodeData("b", record);
        }

        // 示例 4:仅返回某些字段或属性
        System.out.println("仅返回某些字段或属性:");
        Result result4 = session.run("MATCH (p:Person) RETURN p.name, p.age");
        while (result4.hasNext()) {
            Record record = result4.next();
            System.out.println(record.get("p.name") + " " + record.get("p.age"));
        }

        // 示例 5:使用 WHERE 过滤年龄大于 25 的人
        System.out.println("使用 WHERE 过滤年龄大于 25 的人:");
        Result result5 = session.run("MATCH (p:Person) WHERE p.age > 25 RETURN p.name, p.age");
        while (result5.hasNext()) {
            Record record = result5.next();
            System.out.println(record.get("p.name") + " " + record.get("p.age"));
        }

        // 示例 6:查找双向关系(比如互为好友)
        System.out.println("查找双向关系(比如互为好友):");
        Result result6 = session.run("MATCH (a:Person {name: 'Alice'})-[r1:KNOWS]->(b:Person {name: 'Bob'}) " + "MATCH (b)-[r2:KNOWS]->(a) RETURN a, r1, b, r2");
        while (result6.hasNext()) {
            Record record = result6.next();
            System.out.println("===========a===========");
            printNodeData("a", record);
            System.out.println("===========r1===========");
            printRelationshipData("r1", record);
            System.out.println("===========b===========");
            printNodeData("b", record);
            System.out.println("===========r2===========");
            printRelationshipData("r2", record);
        }

        // 示例 7:模糊匹配多个关系类型
        System.out.println("模糊匹配多个关系类型:");
        Result result7 = session.run("MATCH (a:Person {name: 'Alice'})-[:KNOWS|WORKS_WITH]->(b) RETURN b.name");
        while (result7.hasNext()) {
            Record record = result7.next();
            System.out.println(record.get("b.name"));
        }

        // 示例 8:限制返回数量
        System.out.println("限制返回数量:");
        Result result8 = session.run("MATCH (p:Person) RETURN p.name LIMIT 3");
        while (result8.hasNext()) {
            Record record = result8.next();
            System.out.println(record.get("p.name"));
        }
        // 跳过 1 个查询结果并最多返回 3 个 Person 的名字。
        System.out.println("跳过 1 个查询结果并最多返回 3 个 Person 的名字:");
        Result result9 = session.run("MATCH (p:Person) RETURN p.name SKIP 1 LIMIT 3");
        while (result9.hasNext()) {
            Record record = result9.next();
            System.out.println(record.get("p.name"));
        }
    }

    // 3. 更新数据
    private static void updateOperation(Session session) {
        // 示例 1:更新节点的属性
        System.out.println("更新节点的属性:");
        Result result1 = session.run("MATCH (n:Person {name: 'Alice'}) SET n.age = 31 RETURN n");
        while (result1.hasNext()) {
            Record record = result1.next();
            System.out.println("=========================");
            printNodeData("n", record);
        }

        // 示例 2:添加新的属性
        System.out.println("添加新的属性:");
        Result result2 = session.run("MATCH (n:Person {name: 'Bob'}) SET n.email = 'bob@example.com' RETURN n");
        while (result2.hasNext()) {
            Record record = result2.next();
            System.out.println("=========================");
            printNodeData("n", record);
        }

        // 示例 3:一次性设置多个属性
        System.out.println("一次性设置多个属性:");
        Result result3 = session.run("MATCH (n:Person {name: 'Bob'}) SET n.age = 45, n.city = 'Shanghai', n.job = 'Engineer' RETURN n");
        while (result3.hasNext()) {
            Record record = result3.next();
            System.out.println("=========================");
            printNodeData("n", record);
        }

        // 示例 4:删除节点的某个属性
        System.out.println("删除节点的某个属性:");
        Result result4 = session.run("MATCH (n:Person {name: 'Alice'}) REMOVE n.age RETURN n");
        while (result4.hasNext()) {
            Record record = result4.next();
            System.out.println("=========================");
            printNodeData("n", record);
        }

        // 示例 5:删除节点的标签
        System.out.println("删除节点的标签:");
        Result result5 = session.run("MATCH (n:Person {name: 'Bob'}) REMOVE n:Person SET n:User RETURN n");
        while (result5.hasNext()) {
            Record record = result5.next();
            System.out.println("=========================");
            printNodeData("n", record);
        }

        // 示例 6:更新关系属性
        System.out.println("更新关系属性:");
        Result result6 = session.run("MATCH (:Person {name: 'Alice'})-[r:KNOWS]->(:User {name: 'Bob'}) SET r.since = 2021 RETURN r");
        while (result6.hasNext()) {
            Record record = result6.next();
            System.out.println("=========================");
            printRelationshipData("r", record);
        }
    }

    // 4. 删除节点与关系
    private static void deleteOperation(Session session) {
        // 示例 1:删除两个特定节点之间的关系
        System.out.println("删除两个特定节点之间的关系:");
        session.run("MATCH (a:Person {name: 'Alice'})-[r:KNOWS]->(b:Person {name: 'Bob'}) DELETE r");

        // 示例 2:删除特定类型的关系
        System.out.println("删除特定类型的关系:");
        session.run("MATCH ()-[r:KNOWS]->() DELETE r");

        // 示例 3:删除某个特定节点(先删除关系)
        System.out.println("删除某个特定节点(先删除关系):");
        session.run("MATCH (n:Person {name: 'Alice'}) DETACH DELETE n");

        // 示例 4:删除没有关系的孤立节点
        System.out.println("删除没有关系的孤立节点:");
        session.run("MATCH (n) WHERE NOT EXISTS((n)--()) DELETE n");

        // 示例 5:删除所有节点和关系(清空整个图数据库)
        System.out.println("删除所有节点和关系(清空整个图数据库):");
        session.run("MATCH (n) DETACH DELETE n");
    }

    // 5. 合并数据
    private static void mergeOperation(Session session) {
        // 示例 1:确保某节点存在(若不存在则创建)
        System.out.println("确保某节点存在(若不存在则创建):");
        Result result1 = session.run("MERGE (p:Person {name: 'Alice'}) RETURN p");
        while (result1.hasNext()) {
            Record record = result1.next();
            System.out.println("=========================");
            printNodeData("p", record);
        }

        // 示例 2:确保节点存在,并设置额外属性
        System.out.println("确保节点存在,并设置额外属性:");
        Result result2 = session.run("MERGE (p:Person {name: 'Bob'}) SET p.age = 30 RETURN p");
        while (result2.hasNext()) {
            Record record = result2.next();
            System.out.println("=========================");
            printNodeData("p", record);
        }

        // 示例 3:使用 ON CREATE 和 ON MATCH 区分创建与更新操作
        System.out.println("使用 ON CREATE 和 ON MATCH 区分创建与更新操作:");
        Result result3 = session.run("MERGE (p:Person {name: 'Charlie'}) " + "ON CREATE SET p.created = datetime() " + "ON MATCH SET p.lastSeen = datetime() " + "RETURN p");
        while (result3.hasNext()) {
            Record record = result3.next();
            System.out.println("=========================");
            printNodeData("p", record);
        }

        // 示例 4:合并关系(确保两个节点之间有某种关系)
        System.out.println("合并关系(确保两个节点之间有某种关系):");
        Result result4 = session.run("MERGE (a:Person {name: 'Alice'}) " + "MERGE (b:Person {name: 'Bob'}) " + "MERGE (a)-[r:FRIENDS_WITH]->(b) " + "RETURN a, r, b");
        while (result4.hasNext()) {
            Record record = result4.next();
            System.out.println("===========a===========");
            printNodeData("a", record);
        }

        // 示例 5:合并带属性的关系
        System.out.println("合并带属性的关系:");
        Result result5 = session.run("MERGE (a:Person {name: 'Alice'}) " + "MERGE (b:Person {name: 'Bob'}) " + "MERGE (a)-[r:WORKS_WITH {since: 2022}]->(b) " + "RETURN r");
        while (result5.hasNext()) {
            Record record = result5.next();
            System.out.println("=========================");
            printRelationshipData("r", record);
        }
    }
}

2. 项目下载

下载地址:https://download.csdn.net/download/zcs2312852665/90889723?spm=1001.2014.3001.5503

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2386715.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯3503 更小的数

问题描述 小蓝有一个长度均为 n 且仅由数字字符 0∼9 组成的字符串&#xff0c;下标从 0 到 n−1&#xff0c;你可以将其视作是一个具有 n 位的十进制数字 num&#xff0c;小蓝可以从 num 中选出一段连续的子串并将子串进行反转&#xff0c;最多反转一次。 小蓝想要将选出的子…

算法-全排列

1、全排列函数的使用 举例&#xff1a;{1,2,3}的全排列 #include<iostream> #include<bits/stdc.h> using namespace std; typedef long long ll; int main(){ll a[3] {1, 2, 3};do{for (ll i 0; i < 3;i){cout << a[i] << " ";}cout…

最好用的wordpress外贸主题

产品展示独立站wordpress主题 橙色的首页大banner外贸英文wordpress主题&#xff0c;适合用于产品展示型的外贸网站。 https://www.jianzhanpress.com/?p8556 Machine机器wordpress模板 宽屏简洁实用的wordpress外贸建站模板&#xff0c;适合工业机器生产、加工、制造的外贸…

2025 河北ICPC( D. 金泰园(二分)-- C.年少的誓约(公式转化))

文章目录 2025 河北ICPCD. 金泰园&#xff08;二分&#xff09;C.年少的誓约(公式转化)总结 2025 河北ICPC 题目链接&#xff1a; Attachments - The 9th Hebei Collegiate Programming Contest - Codeforces sdccpc20250522 - Virtual Judge 赛时&#xff1a;5道 D. 金泰…

mongodb语法$vlookup性能分析

1 场景描述 mongodb有两个表department和user表&#xff0c; department表有_id,name,level&#xff0c;表有记录169w条 user表有_id,name,department_id&#xff0c;表有记录169w条&#xff0c;department_id没有创建索引&#xff0c;department_id是department的_id。 现…

晶圆隐裂检测提高半导体行业效率

半导体行业是现代制造业的核心基石&#xff0c;被誉为“工业的粮食”&#xff0c;而晶圆是半导体制造的核心基板&#xff0c;其质量直接决定芯片的性能、良率和可靠性。晶圆隐裂检测是保障半导体良率和可靠性的关键环节。 晶圆检测 通过合理搭配工业相机与光学系统&#xff0c…

在 LangChain 中集成 Mem0 记忆系统教程

目录 简介环境准备基础配置核心组件说明1. 提示模板设计2. 上下文检索3. 响应生成4. 记忆存储 工作流程解析使用示例关键特性完整代码与效果 简介 Mem0 是一个强大的记忆系统&#xff0c;可以帮助 AI 应用存储和检索历史对话信息。本教程将介绍如何在 LangChain 应用中集成 Me…

华润电力招聘认知能力测评及性格测评真题题库考什么?

华润电力招聘测评包含逻辑推理、数字推理、语言理解三大类型的问卷。共计58题。测评限时60分钟。其中逻辑推理、数字推理、语言推理分别限时20分钟&#xff0c;如逾时未完成相关测试&#xff0c;测试将自动终止&#xff0c;请注意测评时间。为了确保测评的连贯性&#xff0c;建…

Maven Profile在插件与依赖中的深度集成

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

手机平板等设备租赁行业MDM方案解析

目录 引言&#xff1a;MDM 在租赁行业的重要性日益凸显 用户场景&#xff1a;租赁公司面临的主要挑战 1. 设备丢失、逾期未还 2. 手动配置和恢复效率低 3. 非授权使用频繁 4. 时区设置混乱影响运维 5. 缺乏实时监管能力 EasyControl MDM&#xff1a;租赁设备的远程管控…

如何调试CATIA CAA程序导致的CATIA异常崩溃问题

问题背景&#xff1a;我采用CATIA CAA编写了一个界面的小程序&#xff0c;功能运行成功&#xff0c;但是每次运行完&#xff0c;关闭CATIA的时候&#xff0c;都会弹出这个对话框&#xff0c;这个对话框的意思是CATIA运行崩溃&#xff0c;点击确定后&#xff0c;CATIA就会意外关…

SQL查询效率以及索引设计

1. SQL 查询效率与数据库缓冲池机制 1.1. 数据库缓冲池&#xff08;Buffer Pool&#xff09; 磁盘 I/O 需要消耗的时间很多&#xff0c;而在内存中进行操作&#xff0c;效率则会高很多&#xff0c;为了能让数据表或者索引中的数据随时被我们所用&#xff0c;DBMS 会申请占用内…

day37打卡

知识点回顾&#xff1a;浙大疏锦行 过拟合的判断&#xff1a;测试集和训练集同步打印指标模型的保存和加载 仅保存权重保存权重和模型保存全部信息checkpoint&#xff0c;还包含训练状态 早停策略 作业&#xff1a;对信贷数据集训练后保存权重&#xff0c;加载权重后继续训练50…

分布式缓存:证明分布式系统的 CAP 理论

文章目录 Pre一、分布式系统背景与特点二、CAP 三要素详解三、CAP 定理的反证证明四、CP 架构与 AP 架构对比典型场景 五、CAP 理论在系统设计中的应用六、总结 Pre 分布式缓存&#xff1a;CAP 理论在实践中的误区与思考 分布式缓存&#xff1a;BASE理论实践指南 分布式 - 从…

软件设计师“面向对象设计”真题考点分析——求三连

一、考点分值占比与趋势分析 综合知识历年考察统计 年份考题数分值占比考察重点2018334%继承类型、设计原则2019445.3%多态实现、类关系2020556.7%设计模式应用、接口隔离2021334%消息通信、封装特性2022668%开闭原则、组合模式2023556.7%模板方法、适配器模式2024445.3%单一…

AI大模型学习二十八、ACE-Step:生成式AI音乐大模型简介与安装(一)

一、说明 先来一首创作的歌&#xff1a; 在大模型和生成式AI模型大规模发达的今天&#xff0c;利用大模型生成音乐也是其中一个重要的发展方向。今天我们就介绍一个这样的音乐生成模型ACE-Step&#xff0c;可基于关键字和歌词生成歌曲&#xff1b;基于歌曲生成伴奏等等功能。 …

接口性能测试-工具JMeter的学习

接口登录链接http://111.230.19.204:8080/blog_login.html 一、JMeter基本使用流程 1、启动Jmeter 2、在“测试计划”下添加线程组 3、在“线程组”下添加“HTTP”取样器 4、填写“HTTP请求”的相关请求数据 5、在“线程组”下添加“查看结果树”监听器 6、点击“启动”按钮…

python如何离线安装pandas,numpy

1.首先在有网的电脑上正常安装python&#xff08;和离线环境一样的版本&#xff09; 然后 pip install pandas &#xff08;不嫌麻烦的话也可以自己手动去pandas PyPI​​​​​​​ 一个个下载&#xff09; 安装好后导出相关包&#xff0c;使用如下指令 2.然后相关依赖包就…

Java Swing 自定义JOptionPane

运行后的样式 import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;public class demoB {public static void main(String[] args) {SwingUtilities.invokeLater(() -> {JFrame jf new JFrameDemo();jf.se…

【图像大模型】Stable Diffusion XL:下一代文本到图像生成模型的技术突破与实践指南

Stable Diffusion XL&#xff1a;下一代文本到图像生成模型的技术突破与实践指南 一、架构设计与技术演进1.1 核心架构革新1.2 关键技术突破1.2.1 双文本编码器融合1.2.2 动态扩散调度 二、系统架构解析2.1 完整生成流程2.2 性能指标对比 三、实战部署指南3.1 环境配置3.2 基础…