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

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

给定一组 User 个顶点,我需要找到连接到这些顶点的所有 Chat 个顶点,但没有其他顶点。例如,只有 AliceBob 参与的所有聊天。查询应该对结果进行排序,以便连接到最新消息的聊天是先回来

在我最初的尝试中,我尝试从其中一个用户开始,访问 he/she 参与的所有聊天,并对其进行过滤,以便仅保留所有其他用户作为参与者的聊天。

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 的时间戳与集合和顺序进行匹配?感谢您的指点。

编辑感谢丹尼尔的回答,这是新查询:

边缘、顶点和属性标签在实际产品中略有不同(ChatCONVERSATIONtimestampCREATED_ATparticipatesMEMBER_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)

让我们从示例图开始:

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 参与了聊天 A、B 和 C。
  • Bob 参与了聊天 B 和 C。
  • Caesar 仅参与聊天 C。

因此,如果我们现在要查找包含 Alice 和 Bob 之间对话的聊天记录,我们应该只会找到聊天 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 边的一部分,会更容易和更快。