Ontology edits(本体编辑)¶
In addition to writing functions that read data from the Ontology, you can also write functions that create objects and edit the properties and links between objects. This page documents the object edit APIs available to you in functions. For more details about how edit functions work, refer to the overview page.
For the edits created in a function to actually be applied, Ontology edit functions must be configured as a function-backed Action. Configuring an Action in this way allows you to provide additional metadata, configure permissions, and access the Action in various operational interfaces. As noted in the documentation, running an edit function outside of an Action will not actually modify any object data.
:::callout{theme="warning" title="Warning"} Searching for objects immediately after editing them may return unexpected results. See the Caveats section for details. :::
Define an edit function¶
Functions that edit the Ontology must explicitly declare the entities that will be edited using the Edits type exported from the @osdk/functions package. The following example declares a new type representing edits to the Employee and Ticket object types, as well as a link type between Employee and Ticket. Edits to multiple entities need to be joined with the | operator.
import { Employee, Ticket } from "@ontology/sdk";
import { Edits } from "@osdk/functions";
type OntologyEdit = Edits.Object<Employee> | Edits.Interface<Person> | Edits.Object<Ticket> | Edits.Link<Employee, "assignedTickets">;
You must then declare that the function returns an array of edits of the new type.
export default function createNewTicketAndAssignToEmployee(): OntologyEdit[] {
// ...
}
Construct an Ontology edits batch¶
To perform Ontology edits in a TypeScript v2 function, first construct an Ontology edits batch using the createEditBatch function exported from @osdk/functions, passing the previously declared type as a type argument:
import { Employee, Ticket } from "@ontology/sdk";
import { Client } from "@osdk/client";
import { createEditBatch, Edits } from "@osdk/functions";
type OntologyEdit = Edits.Object<Employee> | Edits.Object<Ticket> | Edits.Link<Employee, "assignedTickets">;
export default function createNewTicketAndAssignToEmployee(client: Client): OntologyEdit[] {
const batch = createEditBatch<OntologyEdit>(client);
// ...
}
This batch is used to keep track of all edits made in a function.
Update properties¶
Object properties¶
Use the update method available on the created batch to modify one or more object properties:
batch.update(employee, { lastName: newName });
If you have not loaded the employee object instance into memory, you can also update it by referencing the object's API name and primary key:
batch.update({ $apiName: "Employee", $primaryKey: 23 }, { lastName: newName });
Subsequent access to the lastName property value of employee later in the same function execution will not reflect the changes that you make when calling update on the edit batch.
Sometimes, it is useful to copy all of the property values of one instance of an object type to another instance. The following example assigns the property values of employee2 to employee1:
batch.update(employee1, employee2);
Note that the primary key property value of an existing object cannot be updated.
Interface properties¶
You can use the update method to modify the interface properties of an object through an Ontology interface. In the example below, the type of person is an Ontology interface, but the underlying instance is an object that implements the Person interface.
The update method takes two arguments both for object types and interfaces. For interfaces, it takes the interface that will be modified and the interface properties to be modified.
batch.update(person, { firstName: newFirstName });
Note that an interface property that is implemented by the primary key property of the underlying object cannot be updated.
Update links¶
For many-to-many links, the link and unlink methods are available on the created batch to add or remove links between objects.
// Assign an employee to an office.
batch.link(employee, "office", office);
// Unassign an office from an employee.
batch.unlink(employee, "office", office);
For one-to-one and one-to-many links, use the update method available on the created batch to modify the foreign key property of the source object. The example below illustrates a one-to-many link. An employee can have multiple tickets, but each ticket can only have one employee.
// Assign a ticket to an employee.
batch.update({ $apiName: "Ticket", $primaryKey: 13 }, { assignedEmployeeId: 52 });
// Unassign a ticket.
batch.update({ $apiName: "Ticket", $primaryKey: 13 }, { assignedEmployeeId: undefined });
As with updating properties, you can also reference either side of the link with an API name and primary key if you have not loaded a concrete instance of the object type previously.
// Assign a ticket to an employee.
batch.link({ $apiName: "Employee", $primaryKey: 23 }, "assignedTickets", { $apiName: "Ticket", $primaryKey: 12 });
// Unassign a ticket from an employee.
batch.unlink({ $apiName: "Employee", $primaryKey: 23 }, "assignedTickets", { $apiName: "Ticket", $primaryKey: 12 });
Create objects¶
Objects¶
You can create new objects using the create method on the edit batch. When creating a new object, you must specify a value for its primary key and can optionally initialize any other properties.
In this example, we create a new Ticket object with the given ID, set its dueDate property, and assign it to the given Employee by modifying the assignedTickets link. To simplify the calculation of the new value of dueDate, we use the luxon library.
import { Employee, Ticket } from "@ontology/sdk";
import { Client, Osdk } from "@osdk/client";
import { createEditBatch, Edits, Integer } from "@osdk/functions";
import { DateTime } from "luxon";
type OntologyEdit = Edits.Object<Employee> | Edits.Object<Ticket> | Edits.Link<Employee, "assignedTickets">;
export default function createNewTicketAndAssignToEmployee(
client: Client,
employee: Osdk.Instance<Employee>,
ticketId: Integer,
): OntologyEdit[] {
const batch = createEditBatch<OntologyEdit>(client);
batch.create(Ticket, {
ticketId,
dueDate: DateTime.now().plus({ days: 7 }).toFormat('yyyy-MM-dd'),
});
// The new ticket does not exist in the Ontology as a concrete instance, but we can link it
// by referencing its API name and primary key.
batch.link(employee, "assignedTickets", { $apiName: "Ticket", $primaryKey: ticketId });
return batch.getEdits();
}
Interfaces¶
You can create new object instances through interfaces by calling the create method and specifying an interface, underlying object type, and a set of interface properties. One of the interface properties supplied must be implemented by the primary key property of the underlying object type.
editBatch.create(Person, {
$objectType: "Employee",
firstName: "John",
lastName: "Doe",
});
Delete objects¶
Objects¶
You can delete an object by calling the delete method on the edit batch.
In this example, we delete all the tickets assigned to the given employee:
for await (const ticket of employee.$link.assignedTickets.asyncIter()) {
batch.delete(ticket);
}
Objects may also be deleted using a primary key instead of an instance:
batch.delete({ $apiName: "Ticket", $primaryKey: 12 });
Interfaces¶
You can delete an object through an interface by calling the delete method.
batch.delete(person);
Edits on struct properties¶
Ontology struct properties for both object and interface types can be edited with TypeScript v2 functions. Struct types in TypeScript v2 are defined using TypeScript interfaces. Struct types in functions can be used to edit Ontology struct properties, as long as they contain the same fields as the struct property, with field names matching the API names of the Ontology struct property fields.
interface Address {
street: string,
city: string,
state: string,
country: string,
zipcode: string,
}
export default function updateEmployeeAddress(
client: Client,
employee: Osdk.Instance<Employee>,
newAddress: Address
): OntologyEdit[] {
const batch = createEditBatch<OntologyEdit>(client);
batch.update(employee, { address: newAddress });
return batch.getEdits();
}
中文翻译¶
本体编辑¶
除了编写从本体(Ontology)读取数据的函数外,您还可以编写创建对象以及编辑对象属性和对象间链接的函数。 本文档介绍了函数中可用的对象编辑 API。 有关编辑函数工作原理的更多详细信息,请参阅概述页面。
要使函数中创建的编辑实际生效,本体编辑函数必须配置为函数支持的操作(function-backed Action)。 以这种方式配置操作(Action)可以为您提供额外的元数据、配置权限,并在各种操作界面中访问该操作。 如文档所述,在操作外部运行编辑函数不会实际修改任何对象数据。
:::callout{theme="warning" title="警告"} 在编辑对象后立即搜索对象可能会返回意外结果。详情请参阅注意事项部分。 :::
定义编辑函数¶
编辑本体的函数必须使用从 @osdk/functions 包导出的 Edits 类型,显式声明将要编辑的实体。以下示例声明了一个新类型,表示对 Employee 和 Ticket 对象类型以及 Employee 和 Ticket 之间链接类型的编辑。对多个实体的编辑需要使用 | 运算符进行连接。
import { Employee, Ticket } from "@ontology/sdk";
import { Edits } from "@osdk/functions";
type OntologyEdit = Edits.Object<Employee> | Edits.Interface<Person> | Edits.Object<Ticket> | Edits.Link<Employee, "assignedTickets">;
然后,您必须声明该函数返回新类型编辑的数组。
export default function createNewTicketAndAssignToEmployee(): OntologyEdit[] {
// ...
}
构建本体编辑批次¶
要在 TypeScript v2 函数中执行本体编辑,首先使用从 @osdk/functions 导出的 createEditBatch 函数构建一个本体编辑批次,并将先前声明的类型作为类型参数传入:
import { Employee, Ticket } from "@ontology/sdk";
import { Client } from "@osdk/client";
import { createEditBatch, Edits } from "@osdk/functions";
type OntologyEdit = Edits.Object<Employee> | Edits.Object<Ticket> | Edits.Link<Employee, "assignedTickets">;
export default function createNewTicketAndAssignToEmployee(client: Client): OntologyEdit[] {
const batch = createEditBatch<OntologyEdit>(client);
// ...
}
该批次用于跟踪函数中执行的所有编辑。
更新属性¶
对象属性¶
使用创建的批次上的 update 方法来修改一个或多个对象属性:
batch.update(employee, { lastName: newName });
如果您尚未将 employee 对象实例加载到内存中,也可以通过引用对象的 API 名称和主键来更新它:
batch.update({ $apiName: "Employee", $primaryKey: 23 }, { lastName: newName });
在同一函数执行的后续操作中访问 employee 的 lastName 属性值,将不会反映您在编辑批次上调用 update 时所做的更改。
有时,将一个对象类型实例的所有属性值复制到另一个实例是很有用的。以下示例将 employee2 的属性值赋给 employee1:
batch.update(employee1, employee2);
请注意,现有对象的主键属性值无法更新。
接口属性¶
您可以使用 update 方法通过本体接口(Ontology interface)修改对象的接口属性。在下面的示例中,person 的类型是一个本体接口,但底层实例是一个实现了 Person 接口的对象。
update 方法对对象类型和接口都接受两个参数。对于接口,它接受将要修改的接口以及要修改的接口属性。
batch.update(person, { firstName: newFirstName });
请注意,由底层对象的主键属性实现的接口属性无法更新。
更新链接¶
对于多对多链接,可以使用创建的批次上的 link 和 unlink 方法来添加或移除对象之间的链接。
// 将员工分配到办公室。
batch.link(employee, "office", office);
// 取消员工与办公室的关联。
batch.unlink(employee, "office", office);
对于一对一和一对多链接,使用创建的批次上的 update 方法来修改源对象的外键属性。下面的示例演示了一对多链接。一个员工可以有多个工单,但每个工单只能有一个员工。
// 将工单分配给员工。
batch.update({ $apiName: "Ticket", $primaryKey: 13 }, { assignedEmployeeId: 52 });
// 取消工单分配。
batch.update({ $apiName: "Ticket", $primaryKey: 13 }, { assignedEmployeeId: undefined });
与更新属性类似,如果您之前没有加载对象类型的具体实例,也可以使用 API 名称和主键来引用链接的任一端。
// 将工单分配给员工。
batch.link({ $apiName: "Employee", $primaryKey: 23 }, "assignedTickets", { $apiName: "Ticket", $primaryKey: 12 });
// 取消员工与工单的关联。
batch.unlink({ $apiName: "Employee", $primaryKey: 23 }, "assignedTickets", { $apiName: "Ticket", $primaryKey: 12 });
创建对象¶
对象¶
您可以使用编辑批次上的 create 方法创建新对象。创建新对象时,必须为其主键指定一个值,并可以选择初始化任何其他属性。
在此示例中,我们使用给定的 ID 创建一个新的 Ticket 对象,设置其 dueDate 属性,并通过修改 assignedTickets 链接将其分配给给定的 Employee。为了简化 dueDate 新值的计算,我们使用了 luxon 库。
import { Employee, Ticket } from "@ontology/sdk";
import { Client, Osdk } from "@osdk/client";
import { createEditBatch, Edits, Integer } from "@osdk/functions";
import { DateTime } from "luxon";
type OntologyEdit = Edits.Object<Employee> | Edits.Object<Ticket> | Edits.Link<Employee, "assignedTickets">;
export default function createNewTicketAndAssignToEmployee(
client: Client,
employee: Osdk.Instance<Employee>,
ticketId: Integer,
): OntologyEdit[] {
const batch = createEditBatch<OntologyEdit>(client);
batch.create(Ticket, {
ticketId,
dueDate: DateTime.now().plus({ days: 7 }).toFormat('yyyy-MM-dd'),
});
// 新工单在本体中并不作为具体实例存在,但我们可以通过引用其 API 名称和主键来链接它。
batch.link(employee, "assignedTickets", { $apiName: "Ticket", $primaryKey: ticketId });
return batch.getEdits();
}
接口¶
您可以通过调用 create 方法并指定接口、底层对象类型以及一组接口属性,通过接口创建新的对象实例。提供的接口属性之一必须由底层对象类型的主键属性实现。
editBatch.create(Person, {
$objectType: "Employee",
firstName: "John",
lastName: "Doe",
});
删除对象¶
对象¶
您可以通过调用编辑批次上的 delete 方法来删除对象。
在此示例中,我们删除分配给给定员工的所有工单:
for await (const ticket of employee.$link.assignedTickets.asyncIter()) {
batch.delete(ticket);
}
也可以使用主键而不是实例来删除对象:
batch.delete({ $apiName: "Ticket", $primaryKey: 12 });
接口¶
您可以通过调用 delete 方法,通过接口删除对象。
batch.delete(person);
结构体属性的编辑¶
对象类型和接口类型的本体结构体(struct)属性都可以使用 TypeScript v2 函数进行编辑。TypeScript v2 中的结构体类型使用 TypeScript 接口定义。函数中的结构体类型可用于编辑本体结构体属性,只要它们包含与结构体属性相同的字段,且字段名称与本体结构体属性字段的 API 名称匹配即可。
interface Address {
street: string,
city: string,
state: string,
country: string,
zipcode: string,
}
export default function updateEmployeeAddress(
client: Client,
employee: Osdk.Instance<Employee>,
newAddress: Address
): OntologyEdit[] {
const batch = createEditBatch<OntologyEdit>(client);
batch.update(employee, { address: newAddress });
return batch.getEdits();
}