2

これは主に設計/効率の問題ですが、SQL db で行う方法とは対照的に、neo4j でこれを処理するための好ましい方法があるかどうかを確認したかったのです。

現在、私は 2 つのモデルを持っています -userevent. 私は と の間にも関係がuserありevent、彼らがイベントに参加することを表明しています。イベントの管理者を代表する最善の方法を見つけたいです。つまり、ユーザーが管理するイベントを照会できるようにしたいと考えています。

admin_ofこれを行う 1 つの方法は、ユーザーと の間に新しい関係を作成することですevent。もう 1 つの方法は、出席関係の管理プロパティを作成することです。何かのようなもの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'
4

1 に答える 1

2

これは私がよく考えていることであり、それ自体がブログの投稿やスクリーンキャストに値するものです。私にはベストプラクティスがありますが、これが最善の方法であるとは言えません。考えていないことがあるかもしれません。ただし、これが私が取り組んでいるものです。

それぞれの大きな長所と短所を突き止めました。余分な関係により、トラバーサルが簡単になり、新しい管理者を簡単に追加できますが、本質的に同じことを行う 2 つの関係のセットを維持することは、完全なドラッグです。私にとっては、それはデータベース内の余分ながらくたではなく、その余分ながらくたを管理するためのすべての余分な作業に関するものです。

一般的に言えば、既存の関係を活用できる場合は、管理情報などの余分な関係を作成しないようにしています。私は2つのプラクティスに落ち着きました:

  • まず、更新で示したように、オブジェクトへのパスをたどることで、基本的な「アクセス権がある/アクセス権がない」を取得できます。友達のイベントだけに絞り込みたい場合は、次のようにします。

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

フレンドから開始すると、関連するイベントのみが返されます。さて、彼らが所有するイベントだけが必要な場合...

  • 整数プロパティ (通常は mine と呼びます) をscoreリレーションシップで使用して、そのユーザーのアクセス レベルを表すことができます。スコアリング規則を設定できるため、整数はクールです。0 は権限なし、50 は編集者、99 は管理者 (そのようなもの) を設定し、「where rel.score > {admin_score}」と言うと、それらのみが取得されます。適切なアクセス レベル以上の関係。それは次のようなものでしょう...

    friend.events(:e, :rel).where("rel.score > {privileged_score}").params(privileged_score: 0).continue_your_chain

whereQueryProxy では最新のノードをターゲットにするため、文字列を使用して独自のパラメーターを設定する必要があることに注意してください.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クエリの一部をより再利用可能にするなどのことを行います。1 つの仕様を修正する必要があります。これは double の問題であり、master にマージされます。数日以内に 4.0 のリリース候補 (RC が必要と思われる場合) をリリースする必要があります。

もう一つ...

他に考慮すべきことは、特権情報のみを返す 2 つのクエリを実行することもできるということです。つまり、ユーザーが表示するはずのすべてのイベントを返し、ビュー内の関係に基づいてフィルター処理します。

<%= @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?呼び出しはサーバー側で処理され、ブール値を返すだけです。それほど高価ではありません。

私はそれが理想的だとは思いません -- 確かに効率は劣ります -- しかし、構築するのははるかに簡単です。いつでもリファクタリングできます。いずれにせよ、いずれリファクタリングが必要になることは予想できます。

于 2014-11-25T23:43:03.730 に答える