How to delete an edge and its reverse edge by attribute id?

Given two vertices of type region, and a directional edge region_region that has an id attribute (e.g. idRoad=123), how would you write a DELETE query to remove that edge according its idRoad attribute? Use case is multiple road edges between two regions. And what about where the edge also has a reverse edge (reverse_region_region with same attribute idRoad) as well?

Thanks,
Martyn

(If i’m reading this correctly) You can use the built-in method called “DELETE Edge”

Example From POSTMAN

Thanks :slight_smile: Yes, the built-in endpoint does work for this purpose.

Was just wondering what the GSQL query might be please, and if that would be less expensive than multiple calls to the built-in endpoint for deleting multiple edges? If not less expensive (performance of multiple calls to endpoint) then perhaps just using the endpoint is okay?

Perhaps a better question is: can you pass an array of attribute values to the filter param of the endpoint? What would the filter_list look like? Comma-separated list?

E.g. Something like:
curl -X DELETE "http://localhost:9000/graph/{graph_name}/edges/region/78/region_region/region/120?filter=id=1,id=2,id=3

Problem is though that the endpoint would not allow filtering of edges when multiple pairs of vertices are involved (would only work for regions with id 78 and 120 in above endpoint call).

Could there be an endpoint like:
curl -X DELETE "http://localhost:9000/graph/{graph_name}/edges/region/region_region?filter=id=1,id=2,id=3

Hi Martyn,

I don’t think you can use the DELETE .../edges/... endpoint the way you described.

  • You must provide the source vertex type and ID (although you do not have to provide the edge type and the target vertex type and ID)
  • The filter can be a comma-separated list of conditions, but all conditions are applied to a vertex at a time, i.e. it’s not like WHERE id IN (1, 2, 3)
  • The conditions are “AND’ed” together, and – obviosuly – id = 1 AND id = 2 AND id = 3 can’t be true
  • You can specify a range, e.g. filter=id>=1,id<=3, but I do not think this is applicable in a real life business use case.

On the other hand, I think that your problem (if I understood it correctly) can be solved in GSQL. You can use DML-sub DELETE statement to delete one or more edges that meet a certain condition. My example below deletes one, but if you modify the WHERE condition and/or you have other SELECT statements before the DELETE that identify a subgraph with the unwanted roads, then you can delete more than one road at a time.

CREATE QUERY del_a_road(INT road_id) FOR GRAPH g3 { 
    start = {region.*};
	
	res =
	    SELECT sv
	    FROM   start:sv -(region_region:e)-> :tv
	    WHERE  e.idRoad == road_id
	    ACCUM  DELETE (e);
}

And alternative approach is to use Query-body DELETE statement:

CREATE QUERY del_roads(SET<INT> roads) FOR GRAPH g3 { 
  
	sv = {region.*};
	
	FOREACH r IN roads DO
	    DELETE e
	    FROM   sv:s -(region_region:e)-> :tv
	    WHERE  e.idRoad == r;
	END;
}

The above example iterates through a list of road IDs, which was (randomly) generated by this query:

CREATE QUERY get_roads(/* Parameters here */) FOR GRAPH g3 RETURNS (SetAccum<INT>) { 
    INT rn;
	SetAccum<INT> @@roads;
	
	start = {region.*};
	rn = second(now());
	PRINT("Road filter: " + to_string(rn)) AS output;
	
	res =
	    SELECT sv
	    FROM   start:sv -(region_region:e)-> region:tv
	    WHERE  float_to_int(fmod(e.idRoad, 60))+2 == rn
	    ACCUM  @@roads += e.idRoad;
	
	RETURN @@roads;
}

The above two queries are brought together in a third one:

CREATE QUERY main_road(/* Parameters here */) FOR GRAPH g3 { 
    SetAccum<INT> @@roads;
	
	@@roads = get_roads();
	
	PRINT(@@roads);
	
	del_roads(@@roads);
	
	PRINT("Done.") AS output;
}
1 Like

On thing I was not sure about is how you established multiple edges between a pair of vertices. My understanding is that only one edge could be there and you need to use an alternative solution to have more than one. E.g. by a “mapping” vertex, something like region –(region_road)→ road –(road_region)→ region
How did you handle it?