[英]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. 实际产品中的边缘,顶点和属性标签(
Chat
是CONVERSATION
, timestamp
是CREATED_AT
, participates
是MEMBER_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()
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.