这主要是一个设计/效率问题,但我想知道是否有一种首选方法可以在neo4j中处理这个问题,而不是我在sql db中如何处理它。
现在我有2个模型 - user
和event
。我还有user
和event
之间的关系来表示他们将参加此次活动。我想弄清楚代表事件管理员的最佳方式。换句话说,我希望能够查询用户所关注的事件。
一种方法是在用户和admin_of
之间创建一个名为event
的新关系。另一种方法是创建参与关系的管理属性。像admin: true
admin_of
查询似乎很简单,但又增加了与db的关系。它也可以在以后处理多个管理员。
我认为可以通过类似的方式查询后一种方式:(来自文档)EnrolledIn.where(since: 2002)
所以我的搜索将包括admin: true
。但是我不知道如何将其链接起来,因为我希望它只是朋友活动。其他where
查询通常基于节点上的属性而不是关系。
后一种方法似乎是一种首选方法,但查询它的正确方法是什么?或者是第一种更简单的方法,即使它增加了额外的关系?
更新 我想出了类似的东西
result = Event.query_as(:event).match("event<-[invite: INVITED]-(user: User)<-[:FRIENDS_WITH]-(user)").where(invite: {admin: /true/}).pluck(:event)
基于
中的详细查询https://github.com/neo4jrb/neo4j/wiki/Search-and-Match
更新2
我现在有这个,但没有得到匹配。什么是开始解决我的查询错误的最佳方法?
current_user.friends.events.query_as(:event).match("event<-[invite]-(user: User)<-[friends_with]-(user)").where(invite: {admin: true}, event: {detail: 'property'}).pluck(:event)
我的用户模型
has_many :both, :events, model_class: 'Event', rel_class: 'Invite'
我的活动模型
has_many :both, :users, model_class: 'User', rel_class: 'Invite'
我的邀请模型已
from_class Event
to_class User
type 'invited'
答案 0 :(得分:2)
这是我想到的很多东西,值得一篇博文或截屏。我有我最好的做法,但不会说这是最好的做法。可能有一些我无法考虑的事情。不过,这就是我正在做的事情。
你确定了每个人的优点和缺点:额外的关系使遍历变得容易并且添加新的管理员很容易,但保持两组基本上做同样事情的关系是完全阻力。对我而言,它甚至不是关于数据库中的额外废话,而是关于管理额外垃圾的所有额外工作。
一般来说,当我可以利用现有的rel时,我会尽量避免为管理信息之类的内容创建额外的关系。我已经确定了两种做法:
首先,您可以获得一个基本的&#34;有访问权限/无法访问&#34;通过跟踪对象的路径,如更新中所示。如果您想将其缩小到只有朋友的事件,请执行以下操作:
friend.events.query_as(:event).match.all_the_rest_of_your_chain
通过为朋友开始,您将只返回与他们相关的事件。现在,如果你只想要他们拥有的活动......
您可以在关系中使用整数属性(我通常称之为我的score
)来表示该用户对其的访问级别。整数很酷,因为你可以设置得分惯例,0是没有权利,50是编辑,99是管理员 - 类似的东西 - 然后说&#34;其中rel.score&gt; {admin_score}&#34;并且您只能获得具有正确访问级别或更高级别的关系。这就像是......
friend.events(:e, :rel).where("rel.score > {privileged_score}").params(privileged_score: 0).continue_your_chain
请注意,我们必须使用字符串并设置我们自己的参数,因为QueryProxy中的where
将定位到最近的节点,我们无法.where(rel: { score: privileged_score })
。 (我计划尽快添加rel_where
方法来处理这个问题,BTW。)
无论如何,只返回朋友的访问级别大于默认值的事件,这意味着某种高级安全级别。
我从那里开始。当您进入更高级的授权问题时,例如&#34;匹配用户拥有事件的事件或拥有事件发生地点的事件,包括特权信息,但有多少特权信息取决于他们拥有哪些项目。 ..如果它们都是什么?&#34;还有一些考虑因素,但我们可以再谈一次。 ; - )
您可能还想阅读https://github.com/neo4jrb/neo4j/wiki/Search-and-Scope的范围。在当前版本中它有点粗糙和错误,但Brian有an open PR进行更新,使其更好。您将能够编写自定义方法:
def privileged_events(score = 0
events(:e, :rel).where("rel.score = {rel_score}").params(rel_score: score)
end
然后执行user.privileged_events.more_query_chain_methods
之类的操作,以使查询更可重用。我们有一个要修复的规范,它只是一个双重问题,它将被合并为主。我们应该在几天内找到4.0候选版本(如果我们认为有必要使用RC)。
还有一件事......
还需要考虑的是,您还可以执行两个查询以仅返回特权信息:返回用户应该看到的所有事件,然后根据视图中的关系进行过滤。
<%= @events.each do |event| %>
<% if @event.users(:u, :rel).where("rel.score = {admin_score}").params(admin_score: 99).include?(current_user) %>
# do stuff
<% end %>
<% end %>
include?
调用将在服务器端处理,只返回一个布尔值,它不是非常昂贵。
我认为这不是理想的 - 它的效率当然不高 - 但它的构建要容易得多。你总是可以重构;地狱,你应该期待你无论如何都需要重构。