ArangoDB与Spring Data集成:删除文档及关联边的方法咨询
Hey there! Let's break down your questions about working with edges and document deletion in ArangoDB + Spring Data step by step:
Absolutely, this is expected behavior by design.
ArangoDB treats edges as independent documents (stored in their own collections), rather than implicit dependencies of the vertex documents they connect. Spring Data ArangoDB doesn't automatically handle cascading deletions of edges when you delete a vertex—you have to explicitly manage this yourself. This gives you full control over how graph relationships are cleaned up, which is useful for complex graph workflows where you might not want to delete all edges every time.
You'll need to query for two types of edges linked to your target document:
- Outgoing edges: Edges where the
_fromfield matches your document's ID - Incoming edges: Edges where the
_tofield matches your document's ID
Option 1: Use custom repository queries
Define these methods in your edge repository interface:
import org.springframework.data.arangodb.repository.ArangoRepository; import org.springframework.data.arangodb.repository.Query; import java.util.List; public interface MyEdgeRepository extends ArangoRepository<MyEdgeEntity, String> { // Find all edges originating from the target document @Query("FOR e IN my_edge_collection FILTER e._from == @docId RETURN e") List<MyEdgeEntity> findOutgoingEdges(String docId); // Find all edges pointing to the target document @Query("FOR e IN my_edge_collection FILTER e._to == @docId RETURN e") List<MyEdgeEntity> findIncomingEdges(String docId); }
Option 2: Use ArangoTemplate
If you prefer working directly with the template:
import com.arangodb.springframework.core.ArangoTemplate; import org.springframework.beans.factory.annotation.Autowired; import java.util.Map; // In your service class @Autowired private ArangoTemplate arangoTemplate; public List<MyEdgeEntity> getAllRelatedEdges(String docId) { // Fetch outgoing edges List<MyEdgeEntity> outgoing = arangoTemplate.query( "FOR e IN my_edge_collection FILTER e._from == @docId RETURN e", Map.of("docId", docId), MyEdgeEntity.class ).asList(); // Fetch incoming edges List<MyEdgeEntity> incoming = arangoTemplate.query( "FOR e IN my_edge_collection FILTER e._to == @docId RETURN e", Map.of("docId", docId), MyEdgeEntity.class ).asList(); outgoing.addAll(incoming); return outgoing; }
Option 1: Delete after fetching
Once you've retrieved the related edges (using the methods above), delete them via the repository:
// In your service public void deleteRelatedEdges(String docId) { List<MyEdgeEntity> edges = myEdgeRepository.findOutgoingEdges(docId); edges.addAll(myEdgeRepository.findIncomingEdges(docId)); myEdgeRepository.deleteAll(edges); }
Option 2: Batch delete with AQL
For better performance (especially with large numbers of edges), use a single AQL query to delete all related edges in one go:
// Add this to your edge repository @Query("FOR e IN my_edge_collection FILTER e._from == @docId OR e._to == @docId REMOVE e IN my_edge_collection") void batchDeleteRelatedEdges(String docId);
To ensure atomicity (so either both the document and edges are deleted, or neither are), use one of these approaches:
Option 1: Manual cascading with transactions
Wrap the deletion steps in a Spring transaction to avoid partial deletions:
import org.springframework.transaction.annotation.Transactional; // In your service @Transactional public void deleteDocumentWithEdges(String docId) { // First delete all related edges myEdgeRepository.batchDeleteRelatedEdges(docId); // Then delete the document relatedRepo.deleteById(docId); }
Option 2: Single AQL query
Combine both deletions into one AQL statement for efficiency:
// Add this to your document repository @Query("LET targetDoc = DOCUMENT(@docId) " + "FOR e IN my_edge_collection FILTER e._from == @docId OR e._to == @docId REMOVE e IN my_edge_collection " + "REMOVE targetDoc IN my_document_collection") void deleteDocumentAndEdges(String docId);
内容的提问来源于stack exchange,提问作者Andrea T

