What are Operations



Why use operations

  • Operations provide management functionality that is Not available in the context of the session, for example:

    • Create/delete a database
    • Execute administrative tasks
    • Assign permissions
    • Change server configuration, and more.
  • The operations are executed on the DocumentStore and are Not part of the session transaction.

  • There are some client tasks, such as patching documents, that can be carried out either via the Session (session.advanced.patch()) or via an Operation on the DocumentStore (PatchOperation).

How operations work

  • Sending the request:
    Each Operation is an encapsulation of a RavenCommand.
    The RavenCommand creates the HTTP request message to be sent to the relevant server endpoint.
    The DocumentStore OperationExecutor sends the request and processes the results.
  • Target node:
    By default, the operation will be executed on the server node that is defined by the client configuration.
    However, server-maintenance operations can be executed on a specific node by using the forNode method.
  • Target database:
    By default, operations work on the default database defined in the DocumentStore.
    However, common operations & maintenance operations can operate on a different database by using the forDatabase method.
  • Transaction scope:
    Operations execute as a single-node transaction.
    If needed, data will then replicate to the other nodes in the database-group.
  • Background operations:
    Some operations may take a long time to complete and can be awaited for completion.
    Learn more below.

Common operations

  • All common operations implement the IOperation interface.
    The operation is executed within the database scope.
    Use forDatabase to operate on a specific database other than the default defined in the store.

  • These operations include set-based operations such as PatchOperation, CounterBatchOperation,
    document-extensions related operations such as getting/putting an attachment, and more.
    See all available operations below.

  • To execute a common operation request,
    use the send method on the operations property in the DocumentStore.

Example:

// Define operation, e.g. get all counters info for a document
$getCountersOp = new GetCountersOperation("products/1-A");

// Execute the operation by passing the operation to Operations.Send
/** @var CountersDetail $allCountersResult */
$allCountersResult = $documentStore->operations()->send($getCountersOp);

// Access the operation result
$numberOfCounters = count($allCountersResult->getCounters());
Syntax:

/**
 * Usage and available overloads:
 *
 *   - send(?OperationInterface $operation, ?SessionInfo $sessionInfo = null): ResultInterface;
 *   - send(string $entityClass, ?PatchOperation $operation, ?SessionInfo $sessionInfo = null): PatchOperationResult;
 *   - send(?PatchOperation $operation, ?SessionInfo $sessionInfo = null): PatchStatus;
 *
 * @param mixed ...$parameters
 */
public function send(...$parameters);

The following common operations are available:


Maintenance operations

  • All maintenance operations implement the IMaintenanceOperation interface.
    The operation is executed within the database scope.
    Use forDatabase to operate on a specific database other than the default defined in the store.

  • These operations include database management operations such as setting client configuration,
    managing indexes & ongoing-tasks operations, getting stats, and more.
    See all available maintenance operations below.

  • To execute a maintenance operation request,
    use the send method on the maintenance property in the DocumentStore.

Example:

// Define operation, e.g. stop an index
$stopIndexOp = new StopIndexOperation("Orders/ByCompany");

// Execute the operation by passing the operation to Maintenance.Send
$documentStore->maintenance()->send($stopIndexOp);

// This specific operation returns void
// You can send another operation to verify the index running status
$indexStatsOp = new GetIndexStatisticsOperation("Orders/ByCompany");
/** @var IndexStats $indexStats */
$indexStats =  $documentStore->maintenance()->send($indexStatsOp);

/** @var IndexRunningStatus $status */
$status = $indexStats->getStatus(); // will be "Paused"
Syntax:

public function send(MaintenanceOperationInterface $operation): ResultInterface;

The following maintenance operations are available:


Server-maintenance operations

  • All server-maintenance operations implement the IServerOperation interface.
    The operation is executed within the server scope.
    Use forNode to operate on a specific node other than the default defined in the client configuration.

  • These operations include server management and configuration operations.
    See all available operations below.

  • To execute a server-maintenance operation request,
    use the send method on the maintenance.server property in the DocumentStore.

Example:

// Define operation, e.g. get the server build number
$getBuildNumberOp = new GetBuildNumberOperation();

// Execute the operation by passing the operation to Maintenance.Server.Send
/** @var BuildNumber $buildNumberResult */
$buildNumberResult = $documentStore->maintenance()->server()->send($getBuildNumberOp);

// Access the operation result
$version = $buildNumberResult->getBuildVersion();
Syntax:

public function send(ServerOperationInterface $operation): ?object;

The following server-maintenance operations are available:


Manage lengthy operations

  • Some operations that run in the server background may take a long time to complete.

  • For Operations that implement an interface with type OperationIdResult,
    executing the operation via the Send method will return an Operation object,
    which can be awaited for completion.


Wait for completion:

public function WaitForCompletionWithTimeout(DocumentStore $documentStore, Duration $duration)
{
    // Define operation, e.g. delete all discontinued products
    // Note: This operation implements interface: 'OperationInterface'
    $deleteByQueryOp = new DeleteByQueryOperation("from Products where Discontinued = true");

    // Execute the operation
    // Send returns an 'Operation' object that can be awaited on

    /** @var Operation $operation */
    $operation = $documentStore->operations()->sendAsync($deleteByQueryOp);

    try {
        // Call method 'waitForCompletion()' to wait for the operation to complete.

        /** @var BulkOperationResult $result */
        $result = $operation->waitForCompletion($duration);

        // The operation has finished within the specified timeframe
        $numberOfItemsDeleted = $result->getTotal(); // Access the operation result


    } catch (TimeoutException $exception) {
        // The operation did Not finish within the specified timeframe
    }

}
Syntax:

/**
 * Wait for operation completion.
 *
 * It throws TimoutException if $duration is set and operation execution time elapses duration interval.
 *
 * Usage:
 *   - waitForCompletion(): void;               // It will wait until operation is finished
 *   - waitForCompletion(Duration $duration);   // It will wait for given duration
 *   - waitForCompletion(int $seconds);         // It will wait for given seconds
 *
 * @param Duration|int|null $duration
 */
public function waitForCompletion(Duration|int|null $duration = null): void;
Parameter Type Description
$duration Duration or int
  • When a duration is specified -
    The server will throw a TimeoutException if the peration has Not completed within the specified time frame.
    The operation itself continues to run in the background,
    no rollback action takes place.
  • null -
    waitForCompletion will wait for the operation to complete indefinitely.