オントロジーの構築ファンクション基礎的なTypeScriptAPI: オントロジー編集

注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。

オントロジーの編集

以下のドキュメントは TypeScript v1 関数に固有の内容です。このページの TypeScript v2 版については、オントロジーの編集を参照してください。オントロジー SDK のサポートやリソースリクエストの設定など、より充実した機能を利用するには、TypeScript v2 への移行をお勧めします。

オントロジーに基づく派生値を返す関数に加えて、オントロジー内のオブジェクトのプロパティやオブジェクト間のリンクを編集する関数も記述できます。このページでは、関数内で利用可能なオブジェクト編集 API について説明します。編集関数の仕組みの詳細については、概要ページを参照してください。

実際の業務で使用するには、オントロジー編集関数をアクションとして設定する必要があります。このようなアクションを関数ベースのアクションと呼びます。この方法でアクションを設定すると、メタデータを追加したり、権限を設定したり、さまざまな業務用インターフェースからアクションにアクセスしたりできます。ドキュメントに記載されているとおり、アクションの外で編集関数を実行しても、オブジェクトデータは実際には変更されません。

オブジェクトを編集した後に検索すると、予期しない結果が返される場合があります。詳細については、留意事項のセクションを参照してください。

編集関数の宣言

オントロジーを編集する関数は、以下の要件を満たす必要があります。

  • @foundry/functions-api からインポートした @OntologyEditFunction() デコレーターを付与する
  • 編集するオブジェクトタイプを指定するために、@foundry/functions-api からインポートした @Edits([object type]) デコレーターを付与する
  • 戻り値の型として void を明示する

プロパティの更新

オブジェクトのプロパティ値を再代入するだけで、プロパティ値を編集できます。たとえば、次のように記述します。

Copied!
1 employee.lastName = newName;

同じ関数の実行中に後から lastName プロパティの値にアクセスすると、先ほど設定した新しい値が返されます。

オブジェクトの配列プロパティは、ReadOnlyArray 型で生成されます。配列を変更するには、コピーを作成してそのコピーを変更し、プロパティを更新します。

Copied!
1 2 3 4 5 6 // 新しい配列にコピーします let arrayCopy = [...myObject.myArrayProperty]; // コピーした配列を変更できるようになりました arrayCopy.push(newItem); // 次にプロパティ値を上書きします myObject.myArrayProperty = arrayCopy;

既存のオブジェクトの主キープロパティの値は更新できません。

リンクの更新

SingleLink インターフェースと MultiLink インターフェースには、リンクの更新に使用できるさまざまなメソッドがあります。

Copied!
1 2 3 4 5 6 7 8 9 10 11 // Employee の上司を設定します employee.supervisor.set(newSupervisor); // Employee の上司をクリアします employee.supervisor.clear(); // 指定した従業員に新しい部下を追加します employee.reports.add(newReport); // 指定した従業員に関連付けられた以前の部下を外します employee.reports.remove(oldReport);

プロパティの更新と同様に、更新後のリンクにアクセスすると、更新内容が反映されます。

オブジェクトの作成

@foundry/ontology-api から利用可能な Objects.create() インターフェースを使用して、新しいオブジェクトを作成できます。新しいオブジェクトを作成する際は、その主キーの値を指定する必要があります。

この例では、指定された ID を持つ新しい Ticket オブジェクトを作成し、dueDate プロパティを設定して、指定された Employee に割り当てます(assignedTickets リンクを変更します)。

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import { OntologyEditFunction, Edits } from "@foundry/functions-api"; import { Employee, Objects, Tickets } from "@foundry/ontology-api"; export class TicketActionFunctions { @Edits(Employee, Tickets) @OntologyEditFunction() public createNewTicketAndAssignToEmployee(employee: Employee, ticketId: Integer): void { const newTicket = Objects.create().ticket(ticketId); newTicket.dueDate = LocalDate.now().plusDays(7); employee.assignedTickets.add(newTicket); } }

オブジェクトの削除

.delete() メソッドを呼び出すと、オブジェクトを削除できます。

この例では、指定された従業員に割り当てられたすべてのチケットを削除します。

Copied!
1 2 const tickets = employee.tickets.all(); tickets.forEach(ticket => ticket.delete());

編集内容の記録方法

オントロジー編集関数が実行されると、オブジェクトに対するすべての更新が関数の基盤によって記録され、関数の実行終了時に返されます。これには、Objects.create() API による新しいオブジェクトの作成、すべてのプロパティの更新、オブジェクトの削除が含まれます。

編集内容は適切にまとめられ、アクションで適用される編集が必要最小限になるように処理されます。たとえば、新しいオブジェクトを作成してからそのプロパティを更新すると、プロパティの更新内容を含む単一のオブジェクト作成編集が返されます。同様に、既存のオブジェクトの複数のプロパティを更新すると、すべてのプロパティの編集内容を含む単一のオブジェクト更新編集が返されます。オブジェクトを削除すると、削除前に行われた他のプロパティの編集内容は消去されます。アトミックなトランザクションを実行するアクションサービスに渡す編集リストを生成するには、関数全体の実行に成功する必要があります。

記録されたオントロジーの編集内容は、関数の実行結果としてリストで返されます。このため、オントロジー編集関数の戻り値の型は void または Promise<void> でなければなりません。実行時の関数の実際の戻り値の型はオントロジーの編集リストになるため、同時に別の値を返すことはできません。

編集内容は、1 回の関数実行のライフサイクル全体を通じて、単一の編集ストアに記録されます。つまり、オブジェクトを作成、更新、削除するヘルパー関数がオントロジー編集関数として公開されていなくても、それらを呼び出すことができます。たとえば、次のように記述します。

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 export class HelperEditFunctions { @Edits(ObjectA, ObjectB) @OntologyEditFunction() public createAndLink(): void { const objectA = this.createObjectA(); const objectB = this.createObjectB(); objectA.linkToB.set(objectB); } /** * これらのヘルパー関数には @OntologyEditFunction() アノテーションが付いていませんが、 * 他の編集関数で使用する新しいオブジェクトを作成できます。 */ private createObjectA(): ObjectA { const objectA = Objects.create().objectA(this.generateRandomId()); objectA.prop1 = "example"; objectA.prop2 = 42; return objectA; } private createObjectB(): ObjectB { const objectB = Objects.create().objectB(this.generateRandomId()); objectB.prop1 = "another example"; return objectB; } /* 必要に応じて主キーを生成します。たとえば、 import { Uuid } from "@foundry/functions-utils"; private generateRandomId(){ return Uuid.random(); } */ }

編集後の値の取得

関数内で編集を行うと、値を読み取る際に、関数の基盤が編集後の値を返します。たとえば、オブジェクトのプロパティを設定してから取得すると、新しい値が返されます。

airplane.departureTime = newDepartureTime;
console.log(airplane.departureTime); // newDepartureTime をログに出力します

オブジェクトを削除すると、そのオブジェクトは検索結果から除外され、プロパティにもアクセスできなくなります。

@Edits デコレーター

アクションでは、権限を適用するために来歴情報が必要になる場合があります。この情報をアクションに渡すには、@Edits デコレーターを使用し、関数が編集内容を返すオブジェクトタイプを指定します。

@Edits デコレーターを使用する際は、以下の点を考慮してください。

  • プロパティを編集する場合は、編集したオブジェクトのタイプを宣言する必要があります。
  • 一対一または一対多のリンクを編集する場合は、外部キープロパティを持つオブジェクトのタイプを宣言する必要があります。
  • 結合テーブルのリンクを編集する場合は、ソースと対象の両方のオブジェクトタイプを宣言する必要があります。

関数はコードの静的解析を行い、参照されているオブジェクトタイプを自動的に検出します。ただし、静的解析では参照を正しく検出_できない場合があります_。参照されているオブジェクトタイプの来歴情報を指定するために、常に @Edits デコレーターを使用することを強くお勧めします。

次の例では、関数によってオブジェクトタイプ Employee と Aircraft が編集されます。

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 import { OntologyEditFunction } from "@foundry/functions-api"; import { Employee, Aircraft, Objects } from "@foundry/ontology-api"; export class MyOntologyEditFunction { @Edits(Aircraft, Employee) @OntologyEditFunction() public myFunction(): void { const x = Objects.search().aircraft().all()[0]; x.businessCapacity = 3; const y = Objects.search().employee().all()[0]; y.department = "HR"; } }

主キーなど、編集で変更されなかった識別子を使用して、以前に編集したオブジェクトを Objects.search() API で取得(または実体化)すると、編集後の値が返されます。これは、オブジェクトの実体化時に、関数の基盤が保留中の編集内容をオブジェクトに適用するためです。これに対し、編集した値に基づくフィルター処理、関連オブジェクトの検索、集計では、関数の実行が終了するまで編集内容は反映されません。詳細については、編集とオブジェクト検索を参照してください。

Copied!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import { OntologyEditFunction } from "@foundry/functions-api"; import { Employee, Objects } from "@foundry/ontology-api"; export class CaveatEditFunctions { @Edits(Employee) @OntologyEditFunction() public async editAndSearch(): Promise<void> { const employeeOne = Objects.search().employee().filter(e => e.id.exactMatch(1)).all()[0]; employeeOne.name = "Bob"; // すでに編集したオブジェクトを取得します const employeeOneAgain = Objects.search().employee().filter(e => e.id.exactMatch(1)).all()[0]; console.log(employeeOneAgain.name); // "Bob" を出力します } }