2017-11-08 35 views
1

私はいくつかのデータを抽出するために特定のグラフを横断する方法を頭の中でラップするいくつかの問題を抱えています。ArangoDb AQLグラフのトラバーサル例をクエリ

"users"のコレクションと "places"のコレクションが与えられています。

また、ユーザーが特定の場所を好きであることを示す「お気に入り」エッジコレクション。 「likes」エッジコレクションには、場所に関するユーザーのレビューを保存するための「レビュー」プロパティもあります。

「フォロー」エッジコレクションは、ユーザーが別のユーザーを追跡していることを示します。

グラフをたどって私が好きなすべての場所を取得するにはどうしたらいいですか?私の場所のレビューと私が従うユーザーのレビューは同じ場所のようにも同じです。 enter image description here

たとえば、上記のグラフ。私はユーザー6327であり、私は両方の場所(7968と16213)を確認しました 私はまた、場所を見直したことがあるユーザー6344に従います。

どのように私が好きな場所と人々のレビュー私は私が好きなのと同じ場所を見直しました。

予想される出力は次のようになります。

[ 
{ 
name:"my name", 
place: "place 1", 
id: 1 
review,"my review about place 1" 
}, 
{ 
name:"my name", 
place: "place 2", 
id: 2 
review,"my review about place 2" 
}, 
{ 
name:"name of the user I follow", 
place: "place 2", 
id: 2 
review,"review about place 2 from the user I follow" 
} 
] 

答えて

1

あり、このクエリを実行するには、いくつかの方法があり、そしてそれはまた、あなたがパラメータを追加したい場所によって異なりますが、簡潔にするために私はあなたが問題に近づく方法の一つを理解するのを助けるために、この非常に冗長な質問を以下に構築しました。

あなたのユーザーレコードの_idを特定し、次に従うすべての友人の_idを見つけて、1つのクエリですべての関連するレビューを解決することです。

私は、以下の異なるアプローチを取る、それはにある:

  • あなたは
  • を書かれているレビューは、あなたが
  • に従う者決定決定あなたは従う人々が
  • を書いたレビューを確認しあなたのクチコミをあなたのフォローしている人々のものと合併してください。

これらをマージすることは可能ですクエリをより最適にまとめることができましたが、どのようなデータが利用できるかを確認するのに役立つように、これを壊して各ステージの出力と最終的な回答を表示する価値があると思いました。

AQLグラフクエリについて理解しておくべき重要なことは、クエリ実行時に頂点、エッジ、パスにアクセスする方法です。

パスはそれ自身のオブジェクトであり、パス情報としてどのように悪用するかを理解するために、そのオブジェクトの内容を調べる価値があります。

このクエリでは、前提としています

  • users文書コレクションが含まれているユーザー
  • places文書コレクションは場所
  • followsエッジコレクションは
  • reviewsエッジコレクションはレビューの人々が
  • を書い追跡する他のユーザー以下のユーザーを追跡が含まれています

注:各レコードにidを指定する場合は、reviewidを使用しました。このIDを知っていれば、userplaceの両方のidが得られます。 review

LET my_reviews = (
    FOR vertices, edges, paths IN 1..1 OUTBOUND "users/6327" reviews 
    RETURN { 
     name: FIRST(paths.vertices).name, 
     review_id: FIRST(paths.edges)._id, 
     review: FIRST(paths.edges).review, 
     place: LAST(paths.vertices).place 
    } 
) 

LET who_i_follow = (
    FOR v IN 1..1 OUTBOUND "users/6327" follows 
    RETURN v 
) 

LET reviews_of_who_i_follow = (
    FOR users IN who_i_follow 
     FOR vertices, edges, paths in 1..1 OUTBOUND users._id reviews 
     RETURN { 
      name: FIRST(paths.vertices).name, 
      review_id: FIRST(paths.edges)._id, 
      review: FIRST(paths.edges).review, 
      place: LAST(paths.vertices).place 
     } 
) 

RETURN { 
    my_reviews: my_reviews, 
    who_i_follow: who_i_follow, 
    reviews_of_who_i_follow: reviews_of_who_i_follow, 
    merged_reviews: UNION(my_reviews, reviews_of_who_i_follow) 
} 

paths.verticesにおける最初の頂点は、開始頂点(users/6327)である

paths.verticesにおける最後の頂点は、例えば、パスの終端でありますあなたはpaths.edgesでの最初のエッジがplace

userはここでのparamを取り、クエリの別のよりコンパクトなバージョン、「あなた」であるユーザーの_idであることをレビューです

に従う者。

LET target_users = APPEND(TO_ARRAY(@user), (
    FOR v IN 1..1 OUTBOUND @user follows RETURN v._id 
)) 

LET selected_reviews = (
    FOR u IN target_users 
     FOR vertices, edges, paths in 1..1 OUTBOUND u reviews 
     LET user = FIRST(paths.vertices) 
     LET place = LAST(paths.vertices) 
     LET review = FIRST(paths.edges) 
     RETURN { 
      name: user.name, 
      review_id: review._id, 
      review: review.review, 
      place: place.place 
     } 
) 

RETURN selected_reviews 
+0

非常によく記述され説明されています。努力に感謝します。 私は、問題を小さなステップに分解しなければならないと感じました。私は間違いを犯したと思います。データを一度に抽出しようとしていました。 同じクエリを解決しようとしているときに、グラフデータベースを通常のRDBMSと比較すると、それほど効率的ではありませんか? – Fouad

+0

助けてくれてうれしいです。グラフ・データベースを使用する必要があるかどうか尋ねることは良い質問です。多対多表を使用する従来のRDBMSデータベースでデータ・モデルをテストする価値があります。グラフデータベースのキーは、大規模なデータセットを処理する場合、RDBMSよりもパフォーマンスが一般的に低下することです。グラフデータベースは、グラフの問題を解決するためのクエリー表記法を提供し、エッジにデータを簡単に保存できます。すべてはRDBMSデータベースで行うことができますが、より多くの作業を行う必要があります。元の質問の範囲を超えて、それは常に質問する価値があります。 –

関連する問題