Neo4j gem-处理管理员关系的首选方法 [英] Neo4j gem - Preferred method to deal with admin relationship

查看:62
本文介绍了Neo4j gem-处理管理员关系的首选方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这主要是一个设计/效率问题,但是我想看看是否有一种首选的方法可以在neo4j中进行处理,而不是在sql db中如何进行处理.

This is mostly a design/efficiency question but I wanted to see if there was a preferred way to handle this in neo4j as opposed to how I would do it in a sql db.

现在我有2个模型-userevent.我在userevent之间也有关系,以表示他们将参加活动.我想找出代表活动管理员的最佳方法.换句话说,我希望能够查询用户管理的事件.

Right now I have 2 models - user and event. I also have a relationship between user and event to represent that they will attend the event. I want to figure out the best way to represent the admin of the event. In other words, I want to be able to query the events that are admined by a user.

一种实现方法是在用户和event之间创建一个称为admin_of的新关系.另一种方法是创建参与关系的admin属性.类似于admin: true

One way to do it is to create a new relationship called admin_of between user and event. Another way is to create an admin property of the attending relationship. Something like admin: true

admin_of查询似乎很简单,但向数据库添加了另一个关系.以后也可以处理多位管理员.

The admin_of query seems easy but adds another relationship to the db. It would be able to handle multi admins later on as well.

后一种方式可能会被这样的查询:(来自文档)EnrolledIn.where(since: 2002),因此我的搜索将包括admin: true.但是我不确定如何将其链接起来,因为我希望它仅是朋友活动.其他where查询通常将属性基于节点而不是关系.

The latter way could be queried by something like this I think: (From documentation) EnrolledIn.where(since: 2002) so my search would include admin: true. However I am not sure how to chain this as I want it to be only friends events. The other where queries usually base the properties on the nodes rather than relationships.

后一种方法似乎是首选方法,但是查询它的正确方法是什么?还是第一种方法即使添加了额外的关系也更易于简化?

The latter method seems like to be a preferred method to do it but what would be the correct way to query it? Or is the first method better for simplicity even though it adds an additional relationship?

更新: 我想出了类似的东西

Update: I came up with something like this

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-并匹配

更新2

我现在有这个,但没有找到比赛.开始剖析查询问题的最佳方法是什么?

I have this right now but not getting a match. What's the best way to start disecting what's wrong with my query?

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'

推荐答案

我认为这是很多事情,值得自己撰写博客文章或截屏.我有我的最佳实践,但我不会说这是最好的方法.可能有些事情我没有考虑过.这就是我正在使用的东西.

This is something I think about a lot and worthy of a blog post or screencast in itself. I have my best practices but wouldn't go as far as to say that this is THE BEST way of doing it. There may be something I haven't considered. Here's what I'm working with, though.

您已了解了每个优点和缺点:额外的关系使遍历变得容易,添加新的管理员也很容易,但是维护两组本质上在做同一件事的关系是一种总的拖累.对我来说,这甚至与数据库中多余的废话无关,而是与管理多余废话有关的所有额外工作.

You nailed the big pros and cons of each: the extra relationship makes traversal easy and adding new admins easy but maintaining two sets of relationships that essentially do the same thing is a total drag. For me, it's not even about the extra crap in the database, it's about all the extra work that goes into managing that extra crap.

通常来说,当我可以利用现有的rel时,我会尽量避免为诸如管理信息之类的东西创建额外的关系.我已经确定了两种做法:

Generally speaking, I try to avoid creating extra relationships for things like administrative info when I can leverage existing rels. I've settled on two practices:

  • 首先,按照更新中显示的那样,通过遵循对象的路径,可以获得基本的具有访问权限/没有访问权限".如果您想将其范围缩小到仅针对朋友的活动,请执行以下操作:

  • First, you can get a basic "has access/doesn't have access" by following a path to an object, as you showed in the update. If you want to narrow that down to only events of friends, do something like this:

friend.events.query_as(:event).match.all_the_rest_of_your_chain

从朋友开始,您将仅返回与他们相关的事件.现在,如果您只想要他们拥有的活动...

By starting for the friend, you will only return events they are related to. Now, if you only want events they own...

  • 您可以在关系中使用整数属性,通常将其称为我的score,以表示该用户对其的访问级别.整数很酷,因为您可以设置评分惯例,0是无权限,50是编辑者,99是admin(类似),然后说"where rel.score> {admin_score}",那么您将只获得那些他们具有正确的访问级别或更高级别的关系.就像...

  • You can use an integer property, I usually call mine score, in the relationship to represent that user's access level to it. Integers are cool because you can set a scoring convention, 0 is no rights, 50 is editor, 99 is admin -- something like that -- and then say "where rel.score > {admin_score}" and you'll get only those relationships where they have the correct access level or greater. That'd be something like...

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方法来处理此问题,顺便说一句.)

Note that we've gotta use a string and set our own param because where in QueryProxy will target the most recent node, we can't do .where(rel: { score: privileged_score }). (I'm planning on adding a rel_where method ASAP to handle this, BTW.)

无论如何,那只会返回朋友的访问级别大于默认访问级别的事件,这意味着某种高级安全级别.

Anyway, that'd return only events of the friend where their access level is greater than the default, which implies some sort of advanced security level.

我将从这里开始.当您遇到更高级的授权问题时,例如匹配用户拥有事件的事件或拥有发生事件的场所的事件,则包括特权信息,但是特权信息的多少取决于他们拥有哪些项目...以及如果两者都呢?"还有更多考虑因素,但我们可以再讨论一次. ;-)

I'd start there. When you get into more advanced authorization questions, like "Match events where the user owns the event OR owns the venue where the event is occurring, include privileged information, but how much privileged information depends on which of those items they own... and what if it's both?" there are some more considerations but we can talk about that another time. ;-)

您可能还想阅读 https://github上的范围. com/neo4jrb/neo4j/wiki/Search-and-Scope .在当前版本中,这有点粗糙和错误,但是Brian为打开了公关进行了更新使它变得更好.您将能够编写一个自定义方法:

You may also want to read up on scope at https://github.com/neo4jrb/neo4j/wiki/Search-and-Scope. It's a little rough and buggy in current release but Brian has an open PR for an update that makes it much better. You'll be able to write a custom method:

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).

And then do something like user.privileged_events.more_query_chain_methods to make pieces of queries more reusable. We have one spec to fix, it's just an issue with a double, and it'll be merged into master. We should have the 4.0 release candidate (if we even think an RC is necessary) out in a few days.

还有一件事...

要考虑的另一件事是,您还可以执行两个查询以仅返回特权信息:返回用户应该看到的所有事件,然后根据视图中的关系进行过滤.

Something else to consider is that you could also do two queries to only return privileged information: return all events the user is supposed to see, then filter based on the relationship in the view.

<%= @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?调用将在服务器端处理,只返回一个布尔值,这并不算昂贵.

That include? call will be handled serverside and just return a boolean, it's not terribly expensive.

我认为这不是理想的选择-它的效率肯定较低-但它的构建要容易得多.您可以随时进行重构;地狱,您应该期望无论如何都需要重构.

I don't think it's ideal -- it's certainly less efficient -- but it is a lot easier to build. You can always refactor; hell, you should expect that you'll need to refactor at some point anyway.

这篇关于Neo4j gem-处理管理员关系的首选方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆