返回顶部
首页 > 资讯 > 精选 >为什么要在Ruby APP中使用Neo4j
  • 898
分享到

为什么要在Ruby APP中使用Neo4j

2023-06-17 05:06:10 898人浏览 八月长安
摘要

为什么要在Ruby APP中使用Neo4j,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。每天,我都需要储存大量的数据,而我可以使用很多工具,比如 postgre

为什么要在Ruby APP中使用Neo4j,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

每天,我都需要储存大量的数据,而我可以使用很多工具,比如 postgresqlMySQLsqlite,Redis 和  MongoDB,当我积累了丰富的经验,并且熟练掌握这些工具的时候,我就不认为他们还有什么乐趣了。我从心里热爱  Ruby,是因为它很有趣并且能让我能用自己的方式做一些很厉害的事情。但是我并没有意识到这样的数据处理工具将会影响我很久,尽管它令我找到了新的乐 趣,所以请让我向你介绍 Neo4j 吧。

什么是 Neo4j?

Neo4j 是图形化的数据库!这意味着它被优化用于管理和查询实体(节点)之间的关系(节点),而不是像一个使用表的关系数据库那样的东西。

为什么这很棒?想象一个没有国外钥匙的世界。数据库中的每个实体的关系之间都十分密切,以至于可以直接引用其他实体。如果你想要引用的关系没有关系 表或者搜索扫面,就只需要几个链接就行了。这***的展现了典型的对象模型。这非常令人兴奋,因为 Neo4j  可以提供很多我们所期待的数据库应该具有的功能,并且为我们提供了工具来查询复杂数据图形。

介绍 ActiceNote

为了链接 Neo4j,我们将使用 neo4j gem。连接到你在 Rails 应用程序中的 Neo4j 的方法,可以在 gem  文档中找到。同时此显示代码的应用程序也可在 GitHub 库中运行 Rails 应用程序(使用 sitepoint 的分支)你可以在你的数据库中运行使用前 rake load_sample_data 命令来填充数据库。

下面是一个关于资产模型的基本案例来源于资产管理的Rails APP

class Asset   include Neo4j::Activenode    property :title    has_many :out, :cateGories, type: :HAS_CATEGORY end

简单解释一下:

Neo4j的GEM给我们的Neo4j:: ActiveNode模块,其中包括我们所做的这个模型

此资产意味着这种模式将负责所有在Neo4j标记资产的节点(除标签一个节点可以有很多的标签发挥类似的作用)

我们有一个title属性来描述各个节点

我们有传出has_many的分类关联。这种关联帮助我们通过下面的数据库HAS_CATEGORY关系找到分类的对象。

有了这个模型,我们可以进行基本的查询来找到一个资产,并得到它的分类

2.2.0 :001 > asset = Asset.first  => #<Asset uuid: "0098d2b7-a577-407a-a9f2-7ec4153cfa60", title: "ICC World Cup 2015 "> 2.2.0 :002 > asset.categories.to_a  => [#<Category uuid: "91cd5369-605c-4aff-aad1-b51d8aa9b5f3", name: "Classification">]

熟悉 ActiveRecord 或者 Mongoid 的任何人会看到找个上百次。为了让它变得更有趣,让我们来定义一个 Category 模型:

class Category   include Neo4j::ActiveNode    property :name    has_many :in, :assets, origin: :categories end

在这里,我们的关联有一个 origin 的选项引用了 资产(asset)模型的 categories 关联。如果我们想要的话,我们可以再一次指定 type: :HAS_CATEGORY

创建Recommendations

如果我们想要获得所有和我们的 资产共享一个 category 的所有 资产(asset)会怎样?

2.2.0 :003 > asset.categories.assets.to_a  => [#<Asset uuid: "d2ef17b5-4dbf-4a99-b814-dee2e96d4a09", title: "WineGraph">, ...]

那这样又会发生什么事?ActiveNode 生成一个数据库查询,指定了一个从我们的 资产(asset)到所有其他共享一个 category 的 资产(asset)的路径。然后数据库会发回那些 资产(asset)给我们。下面给出它用到的查询:

MATCH   asset436, asset436-[rel1:`HAS_CATEGORY`]->(node3:`Category`),   node3<-[rel2:`HAS_CATEGORY`]-(result_assets:`Asset`) WHERE (ID(asset436) = {ID_asset436}) RETURN result_assets  Parameters: {ID_asset436: 436}

这种查询语言叫做 Cypher,它等同于 Neo4j 的 SQL。特别注意括号周围节点和接头的 ASCII 风格所代表的关系。这种 Cypher 查询有点冗余,因为 ActiveNode 在算法上面会生成这些查询。如果一个人去写这种查询,它将会看起来像这样:

MATCH source_asset-[:HAS_CATEGORY]->(:Category)<-[:HAS_CATEGORY]-(result_assets:Asset) WHERE ID(source_asset) = {source_asset_id} RETURN result_assets  Parameters: {source_asset_id: 436}

同时,我也发现 Cypher 比 SQL 要容易并且更强大, 但是我们在这里我们不会担心 Cypher 太多。如果你之后想学习更过关于 Cypher 的知识,你可以查找 totorials 和 refcard。

正如你所看到的,我们可以使用 Neo4j 来跨实体。太了不起了!我们也可以使用带有成对 JOINS 的 SQL 来做到。虽然 Cypher  看起来很酷,但是我们还没有什么重大的突破。假设我们想要使用这些查询来创建一些基于共享 category 的 asset  recommendation 会怎样?我们会想要去对 asset 排序然后按照最多共同 category  来排序。让我们在我们的模型中创建一个方法:

class Asset   ...    Recommendation = Struct.new(:asset, :categories, :score)    def asset_recommendations_by_category(common_links_required = 3)     categories(:c)       .assets(:asset)       .order('count(c) DESC')       .pluck('asset, collect(c), count(c)').reject do |_, _, count|       count < common_links_required     end.map do |other_asset, categories, count|       Recommendation.new(other_asset, categories, count)     end   end end

这里有几个有趣的地方值得注意一下:

  • 我们定义变量作为后续使用链的一部分(c 或者 asset)

  • 我们使用 Cypher 的 collect 函数来给我们一个包含一个共享 category 数组的结果列(参考下面的表)。还要注意,我们得到了完整的对象,不仅仅是列/属性:

asset

collect(c)

count(c)

#<Asset>

[#<Category>]

1

#<Asset>

[#<Category>, #<Category>, &hellip;]

4

#<Asset>

[#<Category>, #<Category>]

2

&hellip;

&hellip;

&hellip;

你注意到这里没有一个 GROUP BY 字句了吗?Neo4j 非常智能地意识到 collect 和 count 是聚合函数,并且在我们的结果中通过非聚合列排序(在这个案例中只有 asset变量)。

注意那条 SQL!

作为***一步,我们能够创建的不仅仅是相同 category 的 recommendation。想象一下我们有下面 Neo4j 子图:

为什么要在Ruby APP中使用Neo4j

除了共享的 category 之外,让我们来解释一下 creators 和 viewers asset 有多少共同之处:

class Asset   ...   Recommendation = Struct.new(:asset, :score)    def secret_sauce_recommendations     query_as(:source)       .match('source-[:HAS_CATEGORY]->(category:Category)<-[:HAS_CATEGORY]-(asset:Asset)').break       .optional_match('source<-[:CREATED]-(creator:User)-[:CREATED]->asset').break       .optional_match('source<-[:VIEWED]-(viewer:User)-[:VIEWED]->asset')       .limit(5)       .order('score DESC')       .pluck(         :asset,         '(count(category) * 2) + (count(creator) * 4) + (count(viewer) * 0.1) AS score').map do |other_asset, score|       Recommendation.new(other_asset, score)     end   end end

在这里我们深入研究并开始构建我们自己的查询。结构一样,但不仅仅是通过在共享 category 的两个 asset 之间查找一条path,  我们也会指定两个更多的可选path。我们可以指定三个可选path,但是 Neo4j 需要使用数据库里边每一个其他的 资产(asset)  来对比我们的 资产(asset)。为我们的 category 节点使用 match 而不是 optional_match,我们要求至少有一个共享  category。这样极大的限制了我们的搜索空间。

在图中有1个共享 category,0个共享 creator 以及两个共享的 viewer。这意味着”Ruby“和”Ruby on Rails“之间的分数将会是:

(1*2) + (0*4) + (2*0.1) =2.2

还要注意,我们在这三条path上的 count 聚合函数上做计算(和排序)。对我来说很酷,它使得我有点兴奋地去思考。。。

容易授权

让我们来处理另外一个普遍的问题。假设你的 CEO 来到你桌子前对你说,“我们已经构建了一个非常棒的 app,但是客户想要能够控制谁可以看他们的东西。你可以建立一些隐私控制吗?”看起来很简单。让我们依赖一个标记来访问私有资产(asset):

class Asset   ...   property :public, default: true    def self.visible_to(user)     query_as(:asset)       .match_nodes(user: user)       .where("asset.public OR asset<-[:CREATED]-user")       .pluck(:asset)   end end

使用这些设计,你可以显示用户可以看到的所有资产(asset),因为资产(asset)是公开的或者因为观察者拥有它。没问题,但同样不是个大问题。在另外一个数据库里边,你可以在两个列/属性上面做搜索。让我们来感受一下!

产品经理来到你身边说,“嘿,谢谢你,但是现在人们想要给其他用户直接访问他们私有的东西”。没问题!你可以创建以个 UI 来让用户添加和移除他们资产(asset)的 VIEWALBE_BY 关系,并且可以这样查询:

class Asset   ...    def self.visible_to(user)     query_as(:asset)       .match_nodes(user: user)       .where("asset.public OR asset<-[:CREATED]-user OR asset-[:VIEWABLE_BY]->user")       .pluck(:asset)   end end

另外这将是一个连接表。你仍在用户可以获取资产(asset)的另外一个路径。花费一些时间来欣赏 Neo4j 无模式的本质。

满足于你的工作日,靠在椅子上和喝着下午茶。当然,前提是社交媒体客户服务代表说“用户喜欢新的功能,但是他们希望能够创建分组以及分配访问分组。 你可以做到吗?并且,能允许任意层次的分组吗?你深深得看着他们的眼睛几分钟,然后说:”当然!“。之后开始变得复杂,来看个例子:

为什么要在Ruby APP中使用Neo4j

如果这些资产都是私人代码,到目前为止给 Matz 和 tenderlove 去访问 Ruby,以及 DHH 去访问 Ruby on Rails。添加分组支持,你开始直接分配分组:

class Asset   ...    def self.visible_to(user)     query_as(:asset)       .match_nodes(user: user)       .where("asset.public  OR asset<-[:CREATED]-user OR asset-[:VIEWABLE_BY]->user OR  asset-[:VIEWABLE_BY]->(:Group)<-[:BELONGS_TO]-user")       .pluck('DISTINCT asset')   end end

这个是很简单的,因为你只需要添加另外一条路径。当然,到目前为止那是我们的旧帽子。 Tenderlove 和 Yehuda  就能够看到”Ruby on  Rails“资源(asset),因为他们是“Railsists”分组的。还要注意:现在一些用户有多个资产(asset)路径(像 Matz 去  Ruby 通过 Rubyists 分组和通过 CREATED 关联)你需要返回 DISTINCT asset。

然而通过一个层次结构组织来指定一个任意的path需要花费你较多的时间。你可以查看Neo4j文档直到你找到一些叫做”variable relationships“的东西并试试:

class Asset   ...    def self.visible_to(user)     query_as(:asset)       .match_nodes(user: user)       .where("asset.public OR asset<-[:CREATED]-user OR asset-[:VIEWABLE_BY]       ->user OR asset-[:VIEWABLE_BY]->(:Group)<-[:HAS_SUBGROUP*0..5]-(:Group)<-[:BELONGS_TO]-user")       .pluck('DISTINCT asset')   end end

这里你已经做到了!这种查询会找到可访问一个 group 的 资产(asset)并且贯穿了0到5的  HAS_SUBGROUP关系,***以一个查看用户是否在***一个 group  里边的检查结束。你是这个故事的男主角,你的公司会为你能够快速做好这项工作而给你奖金。

你可以用 Neo4j 做很多我做不到并且很棒的事情(包括使用它的 amazing WEB interface 去利用 Cyper 查找你的数据)。它不仅仅是一种杰出的方式用一个简单而直观的方式来存储你的数据,而且提供了很多高度联系的数据查询效率的好处(相信我你的数据是高度联系的,尽管你没有意识到)。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网精选频道,感谢您对编程网的支持。

--结束END--

本文标题: 为什么要在Ruby APP中使用Neo4j

本文链接: https://lsjlt.com/news/287363.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 为什么要在Ruby APP中使用Neo4j
    为什么要在Ruby APP中使用Neo4j,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。每天,我都需要储存大量的数据,而我可以使用很多工具,比如 Postgre...
    99+
    2023-06-17
  • 为什么要停止在JavaScript中使用类
    为什么要停止在JavaScript中使用类,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。多年来,OOP(面向对象编程)是软件工程中的事实上的标...
    99+
    2024-04-02
  • 在Activity中为什么要用managedQuery()
    在Activity中使用managedQuery()方法是为了在Android 3.0(API级别11)之前的版本中访问Conten...
    99+
    2023-09-01
    Activity
  • 为什么要在LeetCode中使用Python的NumPy库?
    近年来,人工智能和机器学习的兴起,让编程语言的选择变得更加重要。在算法和数据结构领域,LeetCode已经成为了一个非常受欢迎的学习平台,许多程序员在这里刷题、学习和交流。而在这个过程中,Python的NumPy库也成为了许多程序员喜爱的选...
    99+
    2023-06-22
    numy leetcode 文件
  • 怎么在CSS3中使用ruby-position属性
    怎么在CSS3中使用ruby-position属性?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。属性值before 注音文本会在基础文字上面表示。(默...
    99+
    2023-06-08
  • 为什么永远不要在MySQL中使用UTF-8
    这篇文章给大家介绍为什么永远不要在MySQL中使用UTF-8,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。最近我遇到了一个bug,我试着通过Rails在以“utf8”编码的MariaDB中保存一个UTF-8字符串,然后...
    99+
    2023-06-19
  • 为什么要在PHP中使用Laravel容器加载?
    在PHP中使用Laravel容器加载器是一个非常流行的技术。Laravel容器加载器是一个简单而强大的工具,它可以帮助你更好地组织和管理代码。在本文中,我们将介绍为什么要在PHP中使用Laravel容器加载器,并提供一些示例代码。 什么...
    99+
    2023-09-16
    load laravel 容器
  • 为什么要在 PHP shell 中使用缓存路径?
    PHP shell 是 PHP 编程语言的一个交互式环境,它可以让我们在命令行中直接执行 PHP 代码。在实际的开发中,我们经常需要在 PHP shell 中测试一些代码,以验证其正确性或者快速地尝试一些新的语法特性。然而,PHP shel...
    99+
    2023-06-26
    shell 缓存 path
  • 为什么要在 Spring 中使用 Go 索引函数?
    Spring 是一个流行的 Java 开发框架,它提供了丰富的功能和组件,可以帮助开发人员快速开发高质量的应用程序。在 Spring 中,有一个非常实用的功能是 Go 索引函数,本文将深入探讨为什么要在 Spring 中使用 Go 索引函数...
    99+
    2023-10-11
    索引 spring 函数
  • 为什么不要在 Flutter 中使用全局变量
    目录前言Flutter 中的全局变量是什么?Flutter 中使用全局变量的缺点1. 复杂的代码维护过程2. 全局变量使单元测试变得痛苦3. 全局变量导致“面条&rdqu...
    99+
    2024-04-02
  • MySQL中为什么要使用索引
    小编给大家分享一下MySQL中为什么要使用索引,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!索引是什么?MySQL 官方对索引的...
    99+
    2024-04-02
  • 为什么要使用redis
    这篇文章给大家分享的是有关为什么要使用redis的内容。小编觉得挺实用的,因此分享给大家做个参考。一起跟随小编过来看看吧。为什么要使用redis?redis数据库是将数据存储在内存中的,并且读写内存的速度要...
    99+
    2024-04-02
  • 为什么要使用MySQL
    这篇文章给大家分享的是有关为什么要使用MySQL的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是MySQL  MySQL原本是一个开放源码的关系数据库管理系统,原开发者为瑞典...
    99+
    2024-04-02
  • 为什么要使用GraphQL
    这篇文章主要介绍“为什么要使用GraphQL”,在日常操作中,相信很多人在为什么要使用GraphQL问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”为什么要使用GraphQL”...
    99+
    2024-04-02
  • 为什么要使用video.js
    这篇文章主要介绍为什么要使用video.js,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!为什么要使用video.js? PC端浏览器并不支持video直接播放m3u8格式的视频 手机端各式各样的浏览器定制的vide...
    99+
    2023-06-09
  • 为什么要使用String
    本篇文章为大家展示了为什么要使用String,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。最近在培训课期间指导初学者。任务之一就是要大家完成一个类,要求这个类对key为String类型的map执行d...
    99+
    2023-06-17
  • 为什么要使用Hive
    这篇文章将为大家详细讲解有关为什么要使用Hive,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。什么是HiveHive:由Facebook开源用于解决海量结构化日志的数据统计。 Hive是基于Ha...
    99+
    2023-06-02
  • 为什么要使用docker
    小编给大家分享一下为什么要使用docker,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!    一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。做为开发+运维之间的协作,...
    99+
    2023-06-04
  • 为什么要使用JRebel
    这篇文章给大家分享的是有关为什么要使用JRebel的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。为什么要使用JRebel?  在开发过程中有一个很头疼的问题:每次修改后台代码之后,都需要重新将...
    99+
    2023-06-04
  • User这个词为什么不要在代码中使用
    今天给大家介绍一下User这个词为什么不要在代码中使用。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。当你意识到你在项目开始时做的轻量、简单的设想竟然完全错了时...
    99+
    2023-06-28
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作