Gremlin技术咨询:查找双向连接顶点与忽略反向平行边的连接统计
Hey there! Let's break down your Gremlin questions with practical examples and clear explanations:
To locate pairs of vertices that have edges pointing to each other (e.g., vertex A → vertex B and vertex B → vertex A), you can use traversal steps to verify the reverse edge exists. Here are two straightforward approaches:
Approach 1: Using where with reverse traversal
g.V().as('u') .out('connectsTo').as('v') .where('u', eq('v').by(in('connectsTo'))) .select('u', 'v') .dedup()
This traversal starts at each vertex u, finds all vertices v it points to, then checks if v also points back to u. The dedup() ensures we don't get duplicate pairs like (u,v) and (v,u).
Approach 2: Explicit bidirectional check with match
g.match( __.as('u').outE('connectsTo').inV().as('v'), __.as('v').outE('connectsTo').inV().as('u') ).select('u', 'v').dedup()
This directly matches both directions of the edge between u and v, making the intent of the query crystal clear.
If you want to count unique connections (treating bidirectional edges as a single connection instead of two separate entries), the key is to normalize vertex pairs so (u,v) and (v,u) are treated as identical. Here's how to implement this:
g.V().as('u') .out('connectsTo').as('v') // Normalize pairs by ordering vertices (e.g., by ID) to eliminate reverse duplicates .project('normalizedPair').by(union('u', 'v').order().by(id).fold()) .dedup() // Group by the original vertex and count its unique connections .group().by(select('normalizedPair').unfold().limit(1)).by(count())
The union('u', 'v').order().by(id).fold() step ensures every pair is stored in a consistent order, so reverse edges don't get counted twice. After deduplication, we group by the original vertex and tally its unique connections.
dedup() Directly) Absolutely! There are several ways to detect parallel edges (multiple edges between the same pair of vertices, same direction) without solely using dedup(). Here are a few effective methods:
Method 1: Use groupCount to spot duplicate edge pairs
g.E() // Group edges by their (outVertex, inVertex) pair .groupCount().by(union(outV(), inV()).fold()) // Filter for pairs with more than one edge .unfold().where(values().gt(1)) // Extract and deduplicate vertices involved in parallel edges .select(keys).unfold().dedup()
This groups all edges by their start and end vertices, then filters for groups with multiple edges. We then extract the vertices to get those involved in parallel edges.
Method 2: Traverse from vertices to count outgoing edges per target
g.V().as('u') .group().by(id).by(out('connectsTo').groupCount()) // Filter vertices where any target has more than one incoming edge .unfold().select(values).unfold().where(values().gt(1)) .select(keys).dedup()
This groups each vertex's outgoing edges by their target, then checks if any target has multiple edges. The result is all vertices that have parallel outgoing edges.
Method 3: Explicitly match duplicate edges with match
g.V().as('u').V().as('v') .where('u', neq('v')) .match( __.as('u').outE('connectsTo').as('e1').inV().as('v'), __.as('u').outE('connectsTo').as('e2').inV().as('v'), __.as('e1').neq('e2') ) .select('u', 'v').dedup()
This query matches two distinct edges from u to v, ensuring we only return pairs where parallel edges exist.
内容的提问来源于stack exchange,提问作者pridhvi

