使用 AuraDB 免费版构建 Java 微服务

简介: 使用 AuraDB 免费版构建 Java 微服务

对于今天的冒险,我们希望构建一个 Java 微服务,它连接到 Neo4j AuraDB Free 数据库中的图形数据并与之交互。我们的数据是 Goodreads 数据集的精简版本,其中包括书籍、作者和评论信息。虽然书籍和作者非常适合 MongoDB 等文档数据库,但一旦您将评论添加到组合中,关系的细微差别就会使该项目更适合 AuraDB。这样,我们可以利用不同实体之间的关系来改进基于连接结构的分析。虽然我们在这里所做的一切都对其他数据存储是可行的,但图形数据库极大地简化了对实体连接方式的查询。

   Neo4j 提供了多种部署选项。我们可以启动一个 Docker 容器(就像我们在早期使用 MongoDB 的项目中所做的那样),或者利用名为 AuraDB 的数据库即服务选项和免费套餐。Neo4j 将负责管理数据库,它应该拥有我们需要的一切。

   对于此任务,我们将创建 Neo4j 数据库,加载数据,然后构建一个与数据库交互并为客户端服务提供 API 的微服务。

数据库即服务:AuraDB

   注册和创建 Neo4j AuraDB Free 实例需要几个步骤,例如验证您的电子邮件地址并等待实例启动(需要几分钟)。您可以在我的同事 Michael Hunger 的许多“发现 AuraDB Free”博客文章中找到有关该过程的详细信息以及屏幕截图,例如这篇。

图形数据加载

   实例运行后,我们就可以开始数据加载了。包含书籍的起始文件在今天的代码存储库中提供,此外,该文件夹的自述文件和加载脚本中的说明也可用。自述文件中包含的几个查询允许我们验证数据。

   注意此数据集的较大版本也适合 AuraDB 免费套餐实例,但为了方便和加快加载速度,我们选择保持数据集较小。

应用服务

   是时候开始构建我们的应用程序来提取评论数据了。对于我们的微服务,我们将构建一个带有几个 REST 端点的 Spring Boot 应用程序,以访问连接的 Neo4j 数据库中的数据。

   我们可以使用 Spring Initializr 在 start.spring.io 上整理我们的项目大纲。

   在表单上,我们可以将 、 和 字段保留为 default。在该部分下,我选择更新我个人项目的组名称,但欢迎您也将其保留为默认值。我为工件命名了 ,但命名不一定重要。此部分中的所有其他字段都可以保持原样。在该部分下,我们将需要 、 和 。Spring Data Neo4j 是众多 Spring Data 项目之一,用于连接到各种数据存储,帮助我们映射和访问加载到数据库中的数据。最后,项目模板就完成了,我们可以点击底部的按钮下载项目。ProjectLanguageSpring BootProject Metadataneo4j-java-microserviceDependenciesSpring Reactive WebLombokSpring Data Neo4jGenerate

image.png

注意: Spring Initializr 通过页面右栏中的月亮或太阳图标以深色模式或浅色模式显示。

   Generating 会将项目下载为 ZIP 文件,以便我们可以将其解压缩并在您最喜欢的 IDE 中打开它。

   该文件包含我们在 Spring Initializr 上设置的依赖项和软件版本,因此我们可以移动到文件夹中的文件。在这里,我们想要使用 URI 和数据库凭证连接到我们的 Neo4j 实例。我们通常不希望将数据库凭证嵌入到应用程序中,尤其是因为它是基于云的实例。对这些值进行硬编码可能会意外地授予其他人登录或篡改我们的数据库的权限。pom.xmlapplication.propertiessrc/main/resources

   通常,像数据库凭证这样的配置值会被外部化,并由项目在运行时使用 Spring Cloud Config 等项目读入。但是,配置值超出了本文的范围。现在,我们可以将数据库 URI、用户名、密码和数据库名称嵌入到属性文件中。

#database connection
spring.neo4j.uri=<insert Neo4j URI here>
spring.neo4j.authentication.username=<insert Neo4j username here>
spring.neo4j.authentication.password=<insert Neo4j password here>
spring.data.neo4j.database=<insert Neo4j database here>

注意:Database 应该是 neo4j,除非你专门使用命令来更改默认值。

项目代码

让我们从 domain 类开始浏览 Java 文件。

@Data
@Node
class Review {
    @Id
    @GeneratedValue
    private Long neoId;
    @NonNull
    private String review_id;
    private String book_id, review_text, date_added, date_updated, started_at, read_at;
    private Integer rating, n_comments, n_votes;
}

   这是一个 Lombok 注解,它为 domain 类生成 getter、setters、equals、hashCode 和 toString 方法。它减少了样板代码,所以这很好。接下来是 @Node 注释。这是一个 Spring Data Neo4j 注释,将其标记为 Neo4j 实体类(Neo4j 实体称为节点)。@Data

   在 class 声明中,我们为 class 定义了一些字段 (properties)。'@Id' 注释将字段标记为唯一标识符,并表示该值是由 Neo4j 内部生成的。在我们的下一个字段review_id中,我们有一个 Lombok @NonNull 注释,指定此字段不能为 null。我们还要检索一些其他字段,用于评论文本、日期和评级信息。@GeneratedValue

   接下来,我们需要一个存储库接口,我们可以在其中定义与数据库中的数据交互的方法。

interface ReviewRepository extends ReactiveCrudRepository<Review, Long> {
    Flux<Review> findFirst1000By();
    @Query("MATCH (r:Review)-[rel:WRITTEN_FOR]->(b:Book {book_id: $book_id}) RETURN r;")
    Flux<Review> findReviewsByBook(String book_id);
}

   我们希望这个存储库扩展 ,这将允许我们使用响应式方法和类型来处理数据。然后,我们定义几个方法。虽然我们可以使用 Spring Data 的一些默认方法(在文档的代码示例中列出)的开箱即用的实现,但我们希望进行一些自定义,因此我们将定义我们自己的方法。我们不想使用默认方法,而是只想提取 1,000 个结果,因为提取所有 35,342 条评论可能会使客户端上的结果呈现过程过载。ReactiveCrudRepository.findAll()

   请注意,我们没有任何带有该方法的实现代码(没有查询或逻辑)。相反,我们正在使用 Spring Data 的另一个功能:派生方法。这就是 Spring 根据方法名称构建(即“派生”)查询应该是什么的地方。在我们的示例中,我们的存储库正在处理 reviews (),因此正在查找前 1,000 条评论。通常,此语法会通过查找特定标准 (rating, reviewer, date, etc.) 的结果来继续。但是,由于我们想要提取任何随机的评论集,因此我们可以通过简单地从方法名称中省略 criteria 来欺骗 Spring。这就是我们得到 .findFirst1000By()ReactiveCrudRepository<Review, Long>findFirst1000byfindFirst1000By

   注意:这是一个隐藏的解决方法,一旦你知道它就非常方便,但是如果 Spring 为这些情况提供开箱即用的解决方案,那就太好了。

   我们的下一个方法 () 更简单一些。我们想要查找任何特定书籍的评论,因此我们需要按 查找评论。为此,我们将注释与数据库相关查询语言(即 Cypher for Neo4j)中的查询一起使用。此查询查找为具有指定书籍 ID 的书籍撰写的评论。findReviewsByBook()book_id@Query

   存储库完成后,我们可以编写控制器类,为其他服务设置一些 REST 端点来访问数据。

@RestController
@RequestMapping("/neo")
@AllArgsConstructor
class ReviewController {
    private final ReviewRepository reviewRepo;
    @GetMapping
    String liveCheck() { return "Neo4j Java Microservice is up"; }
    @GetMapping("/reviews")
    Flux<Review> getReviews() { return reviewRepo.findFirst1000By(); }
    @GetMapping("/reviews/{book_id}")
    Flux<Review> getBookReviews(@PathVariable String book_id) { return reviewRepo.findReviewsByBook(book_id); }
}

   Spring 注解将此块指定为 rest 控制器类,并为所有类方法定义高级端点。在类声明中,我们注入 ReviewRepository,以便我们可以利用我们的编写方法。@RestController@RequestMapping

   接下来,我们为每个方法映射端点。该方法使用高级端点返回字符串,确保我们的服务处于活动状态且可访问。我们可以通过添加嵌套端点 () 来执行该方法。此方法使用我们在存储库中编写的方法,并返回一个反应式 Flux<> 类型,我们预计结果中有 0 条或多条评论。liveCheck()/neogetReviews()/reviewsfindFirst1000By()

   我们的最后一个方法具有嵌套端点 ,其中书籍 ID 是一个路径变量,它会根据我们要搜索的书籍而变化。该方法传入指定的书籍 ID 作为 path 变量,然后从存储库中调用该方法并返回 of reviews。/reviews/{book_id}getBookReviews()findReviewsByBook()Flux<>

进行测试

   是时候测试我们的新服务了!我喜欢从下到上启动项目,因此首先要确保 Neo4j AuraDB 实例仍在运行。

注意:AuraDB 免费套餐将在三天后自动暂停。您可以使用实例上的“播放”图标继续。

   接下来,我们需要通过 IDE 或命令行启动我们的应用程序。运行后,我们可以使用以下命令测试应用程序。neo4j-java-microservice

1. 测试应用程序是否处于活动状态:打开浏览器并转到 或 转到 命令行。localhost:8080/neocurl localhost:8080/neo

2. 测试后端评论 api 查找评论:打开浏览器并转到命令行或使用 .localhost:8080/neo/reviewscurl localhost:8080/neo/reviews

3. 测试某本书的 API 查找评论:打开浏览器并转到命令行或使用 .localhost:8080/neo/reviews/178186curl localhost:8080/neo/178186

这是我们服务的 reviews api 结果的结果输出!

image.png

查找 1000 条评论

image.png

按书籍查找评论

结束语

   我们演练了如何使用 Neo4j AuraDB 免费套餐创建图形数据库实例,并为书籍、作者和评论加载数据。然后,我们构建了一个微服务应用程序来连接到云数据库并检索评论。最后,我们通过启动应用程序并访问我们的每个端点来测试我们的所有代码,以确保我们可以访问数据。

   我们可以做更多的事情来扩展我们已经建立的东西。为了保持敏感数据的私密性,但多个服务可以访问,我们可以使用 Spring Cloud Config 之类的东西将我们的数据库凭证外部化。我们还可以将此服务添加到编排工具(如 Docker Compose)中,以一起管理多个服务。另一个探索领域是通过从数据库中提取更多相关实体来更充分地利用图数据优势。


目录
相关文章
|
5天前
|
人工智能 算法 Java
Java与AI驱动区块链:构建智能合约与去中心化AI应用
区块链技术和人工智能的融合正在开创去中心化智能应用的新纪元。本文深入探讨如何使用Java构建AI驱动的区块链应用,涵盖智能合约开发、去中心化AI模型训练与推理、数据隐私保护以及通证经济激励等核心主题。我们将完整展示从区块链基础集成、智能合约编写、AI模型上链到去中心化应用(DApp)开发的全流程,为构建下一代可信、透明的智能去中心化系统提供完整技术方案。
89 3
|
6天前
|
机器学习/深度学习 人工智能 监控
Java与AI模型部署:构建企业级模型服务与生命周期管理平台
随着企业AI模型数量的快速增长,模型部署与生命周期管理成为确保AI应用稳定运行的关键。本文深入探讨如何使用Java生态构建一个企业级的模型服务平台,实现模型的版本控制、A/B测试、灰度发布、监控与回滚。通过集成Spring Boot、Kubernetes、MLflow和监控工具,我们将展示如何构建一个高可用、可扩展的模型服务架构,为大规模AI应用提供坚实的运维基础。
66 0
|
7天前
|
人工智能 Java 物联网
Java与边缘AI:构建离线智能的物联网与移动应用
随着边缘计算和终端设备算力的飞速发展,AI推理正从云端向边缘端迁移。本文深入探讨如何在资源受限的边缘设备上使用Java构建离线智能应用,涵盖从模型优化、推理加速到资源管理的全流程。我们将完整展示在Android设备、嵌入式系统和IoT网关中部署轻量级AI模型的技术方案,为构建真正实时、隐私安全的边缘智能应用提供完整实践指南。
139 3
|
8天前
|
人工智能 监控 Java
Java与AI智能体:构建自主决策与工具调用的智能系统
随着AI智能体技术的快速发展,构建能够自主理解任务、制定计划并执行复杂操作的智能系统已成为新的技术前沿。本文深入探讨如何在Java生态中构建具备工具调用、记忆管理和自主决策能力的AI智能体系统。我们将完整展示从智能体架构设计、工具生态系统、记忆机制到多智能体协作的全流程,为Java开发者提供构建下一代自主智能系统的完整技术方案。
112 4
|
9天前
|
机器学习/深度学习 分布式计算 Java
Java与图神经网络:构建企业级知识图谱与智能推理系统
图神经网络(GNN)作为处理非欧几里得数据的前沿技术,正成为企业知识管理和智能推理的核心引擎。本文深入探讨如何在Java生态中构建基于GNN的知识图谱系统,涵盖从图数据建模、GNN模型集成、分布式图计算到实时推理的全流程。通过具体的代码实现和架构设计,展示如何将先进的图神经网络技术融入传统Java企业应用,为构建下一代智能决策系统提供完整解决方案。
123 0
|
13天前
|
人工智能 缓存 自然语言处理
Java与多模态AI:构建支持文本、图像和音频的智能应用
随着大模型从单一文本处理向多模态能力演进,现代AI应用需要同时处理文本、图像、音频等多种信息形式。本文深入探讨如何在Java生态中构建支持多模态AI能力的智能应用。我们将完整展示集成视觉模型、语音模型和语言模型的实践方案,涵盖从文件预处理、多模态推理到结果融合的全流程,为Java开发者打开通往下一代多模态AI应用的大门。
167 41
|
15天前
|
人工智能 Java API
Java AI智能体实战:使用LangChain4j构建能使用工具的AI助手
随着AI技术的发展,AI智能体(Agent)能够通过使用工具来执行复杂任务,从而大幅扩展其能力边界。本文介绍如何在Java中使用LangChain4j框架构建一个能够使用外部工具的AI智能体。我们将通过一个具体示例——一个能获取天气信息和执行数学计算的AI助手,详细讲解如何定义工具、创建智能体并处理执行流程。本文包含完整的代码示例和架构说明,帮助Java开发者快速上手AI智能体的开发。
432 8
|
16天前
|
人工智能 缓存 监控
使用LangChain4j构建Java AI智能体:让大模型学会使用工具
AI智能体是大模型技术的重要演进方向,它使模型能够主动使用工具、与环境交互,以完成复杂任务。本文详细介绍如何在Java应用中,借助LangChain4j框架构建一个具备工具使用能力的AI智能体。我们将创建一个能够进行数学计算和实时信息查询的智能体,涵盖工具定义、智能体组装、记忆管理以及Spring Boot集成等关键步骤,并展示如何通过简单的对话界面与智能体交互。
407 1
|
19天前
|
人工智能 Java API
构建基于Java的AI智能体:使用LangChain4j与Spring AI实现RAG应用
当大模型需要处理私有、实时的数据时,检索增强生成(RAG)技术成为了核心解决方案。本文深入探讨如何在Java生态中构建具备RAG能力的AI智能体。我们将介绍新兴的Spring AI项目与成熟的LangChain4j框架,详细演示如何从零开始构建一个能够查询私有知识库的智能问答系统。内容涵盖文档加载与分块、向量数据库集成、语义检索以及与大模型的最终合成,并提供完整的代码实现,为Java开发者开启构建复杂AI智能体的大门。
578 58
|
20天前
|
人工智能 Java API
Java与大模型集成实战:构建智能Java应用的新范式
随着大型语言模型(LLM)的API化,将其强大的自然语言处理能力集成到现有Java应用中已成为提升应用智能水平的关键路径。本文旨在为Java开发者提供一份实用的集成指南。我们将深入探讨如何使用Spring Boot 3框架,通过HTTP客户端与OpenAI GPT(或兼容API)进行高效、安全的交互。内容涵盖项目依赖配置、异步非阻塞的API调用、请求与响应的结构化处理、异常管理以及一些面向生产环境的最佳实践,并附带完整的代码示例,助您快速将AI能力融入Java生态。
213 12

热门文章

最新文章