简体   繁体   English

我如何在TinkerPop中比较相等的顶点集?

[英]How can I compare sets of vertices for equality in TinkerPop?

Given a set of User vertices, I need to find all Chat vertices that are connected to those, but no other. 给定一组User顶点,我需要找到与之连接的所有Chat顶点,但无需查找其他顶点。 For instance, all chats that only Alice and Bob participate in. The query should order the results so that the chat connected to the most recent message is returned first. 例如,只有爱丽丝(Alice)鲍勃(Bob)参与的所有聊天。查询应该对结果进行排序,以便首先返回连接到最新消息的聊天。

查询范例

In my initial attempt I tried to start off from one of the users, visit all chats he/she participates in, and filter them so that only those chats remain that have exactly all other users as participants. 在最初的尝试中,我尝试从其中一个用户开始,访问他/她参与的所有聊天,并对它们进行过滤,以便仅保留那些所有其他用户均作为参与者的聊天。

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?

Would this be a suitable approach? 这是合适的方法吗? How can I match against sets and order by the timestamps of linked Messages ? 如何通过链接Messages的时间戳与集合和顺序进行匹配? Thanks for any pointers. 感谢您的指导。

edit Here's the new query thanks to Daniel's answer: 编辑由于Daniel的回答,这是新的查询:

The edge, vertex and property labels are slightly different in the actual product ( Chat is CONVERSATION , timestamp is CREATED_AT , participates is MEMBER_OF ) and part of custom enums. 实际产品中的边缘,顶点和属性标签( ChatCONVERSATIONtimestampCREATED_ATparticipatesMEMBER_OF )和自定义枚举的一部分略有不同。 The vertex array contains all user vertices that should be part of the conversation. 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)

Let's start with sample graph: 让我们从示例图开始:

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()
  • Alice participates in chat A, B and C. 爱丽丝参加聊天A,B和C。
  • Bob participates in chat B and C. 鲍勃参加聊天B和C。
  • Caesar participates in chat C only. es撒只参加聊天C。

Thus if we now look for chats with a conversation between Alice and Bob, we should only find Chat B. And sure enough: 因此,如果我们现在通过Alice和Bob之间的对话来查找聊天,那么我们应该只找到ChatB。并且足够肯定:

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]]

It would be a bit easier and faster if timestamps were part of the contains edges. 如果时间戳是contains边缘的一部分,那会更容易,更快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM