Gremlin技术问询:如何在节点查询结果中同时返回关联边的属性?
Got it, let's tackle this problem. You want to include the edge properties (like color) between your starting vertex (id_vertex) and the outgoing vertices in your API response. There are two straightforward approaches to achieve this—either adjust your Gremlin query directly (the more efficient option) or post-process the results after fetching them. Let's break both down:
This approach handles the data merging directly in the database, reducing unnecessary data transfer and improving performance, especially with large datasets. You can use project or select to fetch both edge and vertex properties, then combine them into a single object.
Here's a modified query using project and map to merge edge and vertex data:
const id_vertex = "1"; const data = await g.V().has(id, id_vertex) .outE() // Fetch outgoing edges from the starting vertex .inV() // Fetch the target vertices connected by those edges .project('vertexProps', 'edgeProps') // Project both vertex and edge properties .by(valueMap().with_('~tinkerpop.valueMap.tokens')) // Get vertex properties (matches your original query) .by(valueMap('color')) // Get only the edge's color property (adjust if you need more edge fields) .map(entry => { // Merge vertex properties with edge color into one object const vertexData = entry.get('vertexProps'); const edgeColor = entry.get('edgeProps').color; return { ...vertexData, edgeColor }; }) .toList();
Alternatively, using select for more explicit reference tracking:
const id_vertex = "1"; const data = await g.V().has(id, id_vertex) .as('source') .outE() .as('connectingEdge') .inV() .as('targetVertex') .select('targetVertex', 'connectingEdge') .by(valueMap().with_('~tinkerpop.valueMap.tokens')) .by(valueMap('color')) .map(result => { const vertex = result.get('targetVertex'); const edge = result.get('connectingEdge'); return { ...vertex, edgeColor: edge.color }; }) .toList();
After running either query, your data array will already include the edgeColor field alongside vertex properties. When you run JSON.stringify(data), you'll get exactly the response format you're looking for.
If you can't adjust the original Gremlin query for some reason, you can fetch vertices and edges separately, then merge the data in your Node.js code. Note that this requires two separate database calls, so it's less efficient than the first method.
const id_vertex = "1"; // Step 1: Fetch original vertex data (your existing query) const vertices = await g.V().has(id, id_vertex) .out() .valueMap() .with_('~tinkerpop.valueMap.tokens') .toList(); // Step 2: Fetch edge data (map target vertex IDs to edge colors) const edges = await g.V().has(id, id_vertex) .outE() .project('targetId', 'edgeColor') .by(inV().id()) // Get the ID of the target vertex .by('color') // Get the edge's color property .toList(); // Step 3: Merge vertex and edge data const data = vertices.map(vertex => { // Find the matching edge for this vertex (you mentioned max one edge between nodes) const matchingEdge = edges.find(edge => edge.targetId === vertex.id); // Add edgeColor to the vertex object (keep array format consistent with other properties) return { ...vertex, edgeColor: matchingEdge ? matchingEdge.edgeColor : [] }; });
This will also produce the exact response structure you need. When you stringify data, you'll get the edgeColor field included in each object.
内容的提问来源于stack exchange,提问作者vyavar ignut

