这主要是一个设计/效率问题,但是我想看看是否有一种首选的方法可以在neo4j中进行处理,而不是在sql db中如何进行处理。
现在我有2个模型-user
和event
。我也有之间的关系user
,并event
表示,他们将参加这次活动。我想找出代表活动管理员的最佳方法。换句话说,我希望能够查询由用户管理的事件。
一种方法是admin_of
在用户和之间创建一个新的关系event
。另一种方法是创建参与关系的admin属性。就像是admin: true
该admin_of
查询似乎很简单,但向数据库添加了另一个关系。以后也可以处理多位管理员。
我认为可以通过以下类似方式查询后一种方式:(来自文档)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'
我认为这是很多事情,值得自己撰写博客文章或截屏。我有我的最佳实践,但我不会说这是最好的方法。可能有些事情我没有考虑过。不过,这就是我正在使用的东西。
您要牢记每个优点和缺点:额外的关系使遍历变得容易,添加新的管理员也很容易,但维护本质上是做同样事情的两组关系却是一团糟。对我来说,这甚至与数据库中多余的废话无关,而与管理多余废话有关的所有额外工作有关。
一般来说,当我可以利用现有的关系时,我会尽量避免为诸如管理信息之类的事物创建额外的关系。我已经确定了两种做法:
首先,按照更新中显示的那样,通过遵循对象的路径,可以获得基本的“具有访问权限/没有访问权限”。如果您想将其范围缩小到仅好友事件,请执行以下操作:
friend.events.query_as(:event).match.all_the_rest_of_your_chain
通过为朋友开始,您将仅返回与他们相关的事件。现在,如果您只想要他们拥有的活动...
您可以score
在关系中使用一个整数属性,我通常将其称为mine ,以表示该用户对其的访问级别。整数很酷,因为您可以设置评分惯例,0是无权限,50是编辑者,99是admin(类似),然后说“ where rel.score> {admin_score}”,那么您只会得到那些他们具有正确的访问级别或更高级别的关系。就像...
friend.events(:e, :rel).where("rel.score > {privileged_score}").params(privileged_score: 0).continue_your_chain
请注意,我们必须使用字符串并设置我们自己的参数,因为where
在QueryProxy中,目标是最新的节点,我们不能这样做.where(rel: { score: privileged_score })
。(我正计划添加一种rel_where
尽快处理此问题的方法,顺便说一句。)
无论如何,那只会返回朋友的访问级别大于默认访问级别的事件,这意味着某种高级安全级别。
我从那里开始。当您遇到更高级的授权问题时,例如“匹配用户拥有事件的事件或拥有发生事件的场所的事件,请包括特权信息,但是特权信息的多少取决于他们拥有哪些项目...以及如果两者都呢?” 还有更多考虑因素,但我们可以再讨论一次。;-)
您可能还想在https://github.com/neo4jrb/neo4j/wiki/Search-and-Scope上阅读范围。在当前版本中,这有点粗糙和错误,但是Brian对其进行了公开的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
,使查询片段更可重用。我们有一个要修复的规范,只是一个问题,有一个双重问题,它将被合并到master中。我们应该在几天之内发布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?
调用将在服务器端处理,仅返回一个布尔值,这并不算昂贵。
我认为这并不理想-它的效率肯定较低-但它的构建要容易得多。您可以随时进行重构;地狱,您应该期望无论如何都需要重构。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句