A.4.5 Adding and Removing Attributes of a Property Graph Subgraph
Oracle Spatial and Graph supports updating attributes (key/value pairs) to a subgraph of vertices and/or edges by using a user-customized operation callback. An operation callback defines a set of conditions that a vertex (or an edge) must meet in order to update it (either add or remove the given attribute and value).
You can define your own attribute operations by implementing the VertexOpCallback
and EdgeOpCallback
API interfaces. You must override the needOp
method, which defines the conditions to be satisfied by the vertices (or edges) to be included in the update operation, as well as the getAttributeKeyName
and getAttributeKeyValue
methods, which return the key name and value, respectively, to be used when updating the elements.
The following code fragment implements a VertexOpCallback
that operates over the smithCollaborator
attribute associated only with Robert Smith collaborators. The value of this property is specified based on the role of the collaborators.
private static class CollaboratorsVertexOpCallback implements VertexOpCallback { private OracleVertexBase m_smith; private List<Vertex> m_smithCollaborators; public CollaboratorsVertexOpCallback(OraclePropertyGraph opg) { // Get a list of Robert Smith'sCollaborators m_smith = (OracleVertexBase) opg.getVertices("name", "Robert Smith") .iterator().next(); Iterable<Vertex> iter = m_smith.getVertices(Direction.BOTH, "collaborates"); m_smithCollaborators = OraclePropertyGraphUtils.listify(iter); } public static CollaboratorsVertexOpCallback getInstance(OraclePropertyGraph opg) { return new CollaboratorsVertexOpCallback(opg); } /** * Add attribute if and only if the vertex is a collaborator of Robert * Smith */ @Override public boolean needOp(OracleVertexBase v) { return m_smithCollaborators != null && m_smithCollaborators.contains(v); } @Override public String getAttributeKeyName(OracleVertexBase v) { return "smithCollaborator"; } /** * Define the property's value based on the vertex role */ @Override public Object getAttributeKeyValue(OracleVertexBase v) { String role = v.getProperty("role"); role = role.toLowerCase(); if (role.contains("political")) { return "political"; } else if (role.contains("actor") || role.contains("singer") || role.contains("actress") || role.contains("writer") || role.contains("producer") || role.contains("director")) { return "arts"; } else if (role.contains("player")) { return "sports"; } else if (role.contains("journalist")) { return "journalism"; } else if (role.contains("business") || role.contains("economist")) { return "business"; } else if (role.contains("philanthropist")) { return "philanthropy"; } return " "; } }
The following code fragment implements an EdgeOpCallback
that operates over the smithFeud
attribute associated only with Robert Smith feuds. The value of this property is specified based on the role of the collaborators.
private static class FeudsEdgeOpCallback implements EdgeOpCallback { private OracleVertexBase m_smith; private List<Edge> m_smithFeuds; public FeudsEdgeOpCallback(OraclePropertyGraph opg) { // Get a list of Robert Smith's feuds m_smith = (OracleVertexBase) opg.getVertices("name", "Robert Smith") .iterator().next(); Iterable<Vertex> iter = m_smith.getVertices(Direction.BOTH, "feuds"); m_smithFeuds = OraclePropertyGraphUtils.listify(iter); } public static FeudsEdgeOpCallback getInstance(OraclePropertyGraph opg) { return new FeudsEdgeOpCallback(opg); } /** * Add attribute if and only if the edge is in the list of Robert Smith's * feuds */ @Override public boolean needOp(OracleEdgeBase e) { return m_smithFeuds != null && m_smithFeuds.contains(e); } @Override public String getAttributeKeyName(OracleEdgeBase e) { return "smithFeud"; } /** * Define the property's value based on the in/out vertex role */ @Override public Object getAttributeKeyValue(OracleEdgeBase e) { OracleVertexBase v = (OracleVertexBase) e.getVertex(Direction.IN); if (m_smith.equals(v)) { v = (OracleVertexBase) e.getVertex(Direction.OUT); } String role = v.getProperty("role"); role = role.toLowerCase(); if (role.contains("political")) { return "political"; } else if (role.contains("actor") || role.contains("singer") || role.contains("actress") || role.contains("writer") || role.contains("producer") || role.contains("director")) { return "arts"; } else if (role.contains("journalist")) { return "journalism"; } else if (role.contains("player")) { return "sports"; } else if (role.contains("business") || role.contains("economist")) { return "business"; } else if (role.contains("philanthropist")) { return "philanthropy"; } return " "; } }
Using the operations callbacks defined previously, the following code fragment loads a property graph, creates an instance of the operation callbacks, and later adds the attributes into the pertinent vertices and edges using the addAttributeToAllVertices
and addAttributeToAllEdges
methods in OraclePropertyGraph
.
OraclePropertyGraph opg = OraclePropertyGraph.getInstance( args, szGraphName); // Clear existing vertices/edges in the property graph opg.clearRepository(); String szOPVFile = "../../data/connections.opv"; String szOPEFile = "../../data/connections.ope"; // This object will handle parallel data loading OraclePropertyGraphDataLoader opgdl = OraclePropertyGraphDataLoader.getInstance(); opgdl.loadData(opg, szOPVFile, szOPEFile, dop); // Create the vertex operation callback CollaboratorsVertexOpCallback cvoc = CollaboratorsVertexOpCallback.getInstance(opg); // Add attribute to all people collaborating with Smith based on their role opg.addAttributeToAllVertices(cvoc, true /** Skip store to Cache */, dop); // Look up for all collaborators of Smith Iterable<Vertex> collaborators = opg.getVertices("smithCollaborator", "political"); System.out.println("Political collaborators of Robert Smith " + getVerticesAsString(collaborators)); collaborators = opg.getVertices("smithCollaborator", "business"); System.out.println("Business collaborators of Robert Smith " + getVerticesAsString(collaborators)); // Add an attribute to all people having a feud with Robert Smith to set // the type of relation they have FeudsEdgeOpCallback feoc = FeudsEdgeOpCallback.getInstance(opg); opg.addAttributeToAllEdges(feoc, true /** Skip store to Cache */, dop); // Look up for all feuds of Smith Iterable<Edge> feuds = opg.getEdges("smithFeud", "political"); System.out.println("\n\nPolitical feuds of Robert Smith " + getEdgesAsString(feuds)); feuds = opg.getEdges("smithFeud", "business"); System.out.println("Business feuds of Robert Smith " + getEdgesAsString(feuds));
The following code fragment defines an implementation of VertexOpCallback
that can be used to remove vertices having value philanthropy for attribute smithCollaborator
, then call the API removeAttributeFromAllVertices
; It also defines an implementation of EdgeOpCallback
that can be used to remove edges having value business for attribute smithFeud
, then call the API removeAttributeFromAllEdges
.
System.out.println("\n\nRemove 'smithCollaborator' property from all the" + "philanthropy collaborators"); PhilanthropyCollaboratorsVertexOpCallback pvoc = PhilanthropyCollaboratorsVertexOpCallback.getInstance(); opg.removeAttributeFromAllVertices(pvoc); System.out.println("\n\nRemove 'smithFeud' property from all the" + "business feuds"); BusinessFeudsEdgeOpCallback beoc = BusinessFeudsEdgeOpCallback.getInstance(); opg.removeAttributeFromAllEdges(beoc); /** * Implementation of a EdgeOpCallback to remove the "smithCollaborators" * property from all people collaborating with Robert Smith that have a * philanthropy role */ private static class PhilanthropyCollaboratorsVertexOpCallback implements VertexOpCallback { public static PhilanthropyCollaboratorsVertexOpCallback getInstance() { return new PhilanthropyCollaboratorsVertexOpCallback(); } /** * Remove attribute if and only if the property value for * smithCollaborator is Philanthropy */ @Override public boolean needOp(OracleVertexBase v) { String type = v.getProperty("smithCollaborator"); return type != null && type.equals("philanthropy"); } @Override public String getAttributeKeyName(OracleVertexBase v) { return "smithCollaborator"; } /** * Define the property's value. In this case can be empty */ @Override public Object getAttributeKeyValue(OracleVertexBase v) { return " "; } } /** * Implementation of a EdgeOpCallback to remove the "smithFeud" property * from all connections in a feud with Robert Smith that have a business role */ private static class BusinessFeudsEdgeOpCallback implements EdgeOpCallback { public static BusinessFeudsEdgeOpCallback getInstance() { return new BusinessFeudsEdgeOpCallback(); } /** * Remove attribute if and only if the property value for smithFeud is * business */ @Override public boolean needOp(OracleEdgeBase e) { String type = e.getProperty("smithFeud"); return type != null && type.equals("business"); } @Override public String getAttributeKeyName(OracleEdgeBase e) { return "smithFeud"; } /** * Define the property's value. In this case can be empty */ @Override public Object getAttributeKeyValue(OracleEdgeBase e) { return " "; } }
Parent topic: Using Java APIs for Property Graph Data