There are three different types of edits that can be applied to a knowledge graph:
- Add new entities and relationships to the graph
- Update the properties of entities and relationships that already exist in the graph
- Delete entities and relationships from the graph.
Define edits
Add new records
To specify new records to add to the graph, first define any new entities and relationships and
their properties. These properties must match the properties of the
entity type or relationship type that the record is being added to.
For example, if you are adding an entity to the Supplier
entity type, and the Supplier
entity type has the two properties Name
, which is a required property, and employee
,
the new entity can only contain those two properties and must contain Name
because it is required.
When adding a relationship, the origin and destination entities must already exist in the graph.
//create new entity and relationship to add to the graph
const newEntity = new Entity({
typeName: "Supplier",
properties: {
Name: "Supplier 5",
employee_count: 681
}
});
const newRelationship = new Relationship({
typeName: "buys_part",
properties: {
quantity: 5000
},
//origin and destination entities must already exist in the graph
originId: "{1W5F4WA1-2A5W-1A5W-ANIW-1A5W4F8W4A1W}",
destinationId: "{70CEBB71-3C04-4761-9026-3A761D471D09}"
});
Update existing records
To define updates to existing records, specify entity or relationship objects with ID's that are already in the graph. Record property values can be
changed or added provided that the property exits for the named type. For example, if we added an entity of the Supplier
entity type but only included the required Name
property when we created it, we could update that entity by adding a value for the employee
. Properties themselves cannot be added or deleted since they are associated
with the entity type or relationship type. For information on adding or removing properties from a named type see ArcGIS REST API: Knowledge Graph Service - Edit (Data Model)
//update existing records
const updateEntity1 = new Entity({
typeName: "Supplier",
//update the Employee_count from 681 to 685
properties: {
Name: "Supplier 5",
employee_count: 685
},
id: "{1W5F4WA1-2A5W-1A5W-ANIW-1W5A1A5W4F8W}" //id of entity already in knowledge graph
});
const updateEntity2 = new Entity({
typeName: "Supplier",
//update the Employee_count from 700 to 750
properties: {
Name: "Supplier 6",
employee_count: 750
},
id: "{8RDJ5R7-D1R4-E95H-D4R7-DR5D8R4EW3}" //id of entity already in knowledge graph
});
const updateRelationship = new Relationship({
typeName: "buys_part",
//update the quantity from 5000 to 5500
properties: {
quantity: 5500
},
id: "{1W5F4WA1-2A5W-1A5W-ANIW-9W5G4R8DJ7R2}" //id of relationship already in knowledge graph
});
Delete records
Specify records to delete by specifying the entity type or relationship type and a list of record ID's of that type to be deleted.
Note that by default when deleting an entity you must also specify all connected relationships for deletion as well.
If you want these relationships to be deleted automatically, set cascade
to true
when creating your GraphApplyEdits object (see Apply Edits section for more details).
//for each entity type,
//provide a list of IDs for the entities to be deleted
const delEntities = [
{
typeName: "Supplier",
ids: ["{B1T9J5SK-1A9W-1A5W-19S6-1S9E4H8LC3TS}", "{1A9W6JM1-96A8-1A5W-1A6W-1A6W4K8PD26J}"]
},
{
typeName: "Part",
ids: ["{1B9E4S2D-2A5W-1S6E-ANIW-1S8E49G5E2S4}"]
}
];
//for each relationship type,
//provide a list of IDs for the relationships to be deleted
const delRelationships = [
{
typeName: "buys_part",
ids: ["{T5DR8R1F-R4D8-94ES-JR5D-1D2R5S94G7ES}"]
}
];
Apply edits
Apply the edits to the knowledge graph using executeApplyEdits(). The knowledge graph must be defined and loaded before it can be used to apply edits. If deleting entities, specify whether or not to automatically delete all connected relationships. See GraphApplyEdits for more information on the options parameter. The results identify any errors that occurred applying the edits and lists the IDs of all modified records of each named type.
//define the function to update the graph
const applyEdits = async () => {
//fetch knowledge graph.
//The knowledge graph must be loaded with a data model before other operations can be performed on it.
let knowledgeGraph = await KnowledgeGraphModule.fetchKnowledgeGraph(url);
//search the knowledge graph
KnowledgeGraphModule.executeApplyEdits(
//knowledge graph resources
knowledgeGraph,
//edits to the graph. Autocasts as new GraphApplyEdits
{
entityAdds: [newEntity],
entityUpdates: [updateEntity1, updateEntity2],
entityDeletes: delEntities,
relationshipAdds: [newRelationship],
relationshipUpdates: [updateRelationship],
relationshipDeletes: delRelationships,
//delete all relationships connected to the deleted entities.
options: {
cascadeDelete: true
}
}
).then((applyEditResults) => {
//review the results and notify the user of any errors.
console.log(applyEditResults);
if (applyEditResults.hasError) {
alert(`Error Code: ${applyEditResults.error.errorCode}\nMessage: ${applyEditResults.error.errorMessage}`);
}
//otherwise, review the edits made
else {
let edits = applyEditResults.editResults;
let editSummary = "";
for (let type in edits) {
let edit = edits[type];
let added = edit.adds.map(getEditedIds);
let updated = edit.updates.map(getEditedIds);
let deleted = edit.deletes.map(getEditedIds);
editSummary += `<div><h3>${edit.typeName} edits</h3>
<p>Added IDs: ${added.length > 0 ? added.join(", ") : "None"}</p>
<p>Updated IDs: ${updated.length > 0 ? updated.join(", ") : "None"}</p>
<p>Deleted IDs: ${deleted.length > 0 ? deleted.join(", ") : "None"}</p>
</div>`;
}
document.getElementById("viewDiv").innerHTML = editSummary;
}
});
};
//call apply edits function
applyEdits();
//helper function to extract the Ids of the modified records from the edit results
function getEditedIds(record) {
return record.id;
}