2017-08-02 3 views
0

頂点の集合がUserの場合、それらに接続されている頂点はすべて見つけ出す必要がありますが、それ以外の頂点はありません。たとえば、すべてのチャットがアリスボブに参加します。クエリは、最新のメッセージに接続されたチャットが最初に返されるように結果を並べる必要があります。参加者とまったく他のすべてのユーザーを持っている私は、それらのチャットが残るように、ユーザの一人から始め、彼/彼女はに参加し、すべてのチャットを訪問し、それらをフィルタリングしようとした私の最初の試みでTinkerPopで等しくなるように頂点のセットを比較するにはどうすればよいですか?

Query Example

traversal().V(user.id()) //random user of the set 
      .out("participates") 
      .hasLabel("Chat") 
      .where(__.in("participates") 
        .hasLabel("User") 
        .fold()) //how could I match this collection against my set? 

これは適切なアプローチですか?リンクされたタイムスタンプでセットとオーダーを照合するにはどうすればいいですか?Messages?任意のポインターをありがとう。

編集はここでダニエルの答えに、新しいクエリのおかげだ:

エッジ、頂点及び財産のラベルは、実際の製品では、わずかに異なっている(ChattimestampCREATED_ATで、CONVERSATIONで、participatesMEMBER_OFである)との一部カスタム列挙型。 vertex配列には、会話の一部であるべきすべてのユーザー頂点が含まれています。

traversal().V(vertices[0].id()) 
      .out(EdgeLabel.MEMBER_OF.name()) 
      .hasLabel(VertexLabel.CONVERSATION.name()) 
      .filter(__.in(EdgeLabel.MEMBER_OF.name()) 
        .hasLabel(VertexLabel.USER.name()) 
        .is(P.within(vertices)).count().is(vertices.length)) 
      .order().by(__.out(EdgeLabel.CONTAINS.name()) 
         .values(PropertyKey.CREATED_AT.name()) 
         .order().by(Order.decr).limit(1), Order.decr) 

答えて

4

のは、サンプルのグラフを見てみましょう:

g = TinkerGraph.open().traversal() 
g.addV("user").property("name", "alice").as("a"). 
    addV("user").property("name", "bob").as("b"). 
    addV("user").property("name", "caesar").as("c"). 
    addV("chat").property("name", "A").as("A"). 
    addV("chat").property("name", "B").as("B"). 
    addV("chat").property("name", "C").as("C"). 
    addV("message").property("timestamp", 1).property("text", "Sed mollis velit.").as("m1"). 
    addV("message").property("timestamp", 2).property("text", "Aenean aliquet dapibus.").as("m2"). 
    addV("message").property("timestamp", 3).property("text", "Nunc vel dignissim.").as("m3"). 
    addV("message").property("timestamp", 4).property("text", "Aliquam in auctor.").as("m4"). 
    addV("message").property("timestamp", 5).property("text", "Nulla dignissim et.").as("m5"). 
    addV("message").property("timestamp", 6).property("text", "Pellentesque semper dignissim.").as("m6"). 
    addE("participates").from("a").to("A"). 
    addE("participates").from("a").to("B"). 
    addE("participates").from("a").to("C"). 
    addE("participates").from("b").to("B"). 
    addE("participates").from("b").to("C"). 
    addE("participates").from("c").to("C"). 
    addE("contains").from("A").to("m1"). 
    addE("contains").from("A").to("m2"). 
    addE("contains").from("B").to("m3"). 
    addE("contains").from("B").to("m4"). 
    addE("contains").from("C").to("m5"). 
    addE("contains").from("C").to("m6").iterate() 
  • アリスがチャットAに参加し、BとCの
  • ボブがチャットBに参加し、C.
  • シーザーは、チャットに参加しますCのみ。

私たちは今、アリスとボブの間の会話とのチャットを探している場合このように、我々は唯一のB.そして案の定チャット見つける必要があります。

gremlin> g.V(users.head()). 
      out("participates"). 
      not(__.in("participates").is(without(users))). 
      filter(__.in("participates").is(within(users)).count().is(users.size())). 
      order().by(out("contains").values("timestamp").order().by(decr).limit(1), decr). 
      valueMap() 
==>[name:[B]] 

タイムスタンプがいた場合、それは少し簡単かつ迅速になりますcontainsエッジの一部。

+0

この優雅なクエリに感謝します。私はそれが何をすべきかを確実にするために様々なテストケースを書いた。これは、与えられたユーザを参加者として持つ「チャット」頂点を返すが、それだけではない。 A、B、Cがチャット中で、AとBだけのチャットを求めているように、私も3つともチャットを取得します。 '.is(within(...))。count()。is(...)'の連結と関係があると思いますか?現在の(Java)クエリについては、私の編集した質問をご覧ください。 –

+0

あなたは完全一致したいと言っていますか?例えば。あなたがAとBを求めているなら、AとBはこのチャットの唯一の参加者であるべきですか? –

+0

そうです。 '.is(within users) 'は、会話の一部ではないすべてのユーザをフィルタリングします。つまり、' .count()。(users.size()) 'は常に' true'にマップされます。すべてのユーザーがチャットに参加していれば、それ以上のチャットがあっても関係ありません。どう思いますか? –

関連する問題