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
IOperation<CountersDetail> getCountersOp = new GetCountersOperation("products/1-A");

// Execute the operation by passing the operation to Operations.Send
CountersDetail allCountersResult = documentStore.Operations.Send(getCountersOp);

// Access the operation result
int numberOfCounters = allCountersResult.Counters.Count;
// Define operation, e.g. get all counters info for a document
IOperation<CountersDetail> getCountersOp = new GetCountersOperation("products/1-A");
    
// Execute the operation by passing the operation to Operations.Send
CountersDetail allCountersResult = await documentStore.Operations.SendAsync(getCountersOp);

// Access the operation result
int numberOfCounters = allCountersResult.Counters.Count;

Send syntax:

// Available overloads:
void Send(IOperation operation, SessionInfo sessionInfo = null);
TResult Send<TResult>(IOperation<TResult> operation, SessionInfo sessionInfo = null);
Operation Send(IOperation<OperationIdResult> operation, SessionInfo sessionInfo = null);

PatchStatus Send(PatchOperation operation);
PatchOperation.Result<TEntity> Send<TEntity>(PatchOperation<TEntity> operation);
// Available overloads:
Task SendAsync(IOperation operation,
    CancellationToken token = default(CancellationToken), SessionInfo sessionInfo = null);
Task<TResult> SendAsync<TResult>(IOperation<TResult> operation,
    CancellationToken token = default(CancellationToken), SessionInfo sessionInfo = null);
Task<Operation> SendAsync(IOperation<OperationIdResult> operation,
    CancellationToken token = default(CancellationToken), SessionInfo sessionInfo = null);

Task<PatchStatus> SendAsync(PatchOperation operation,
    CancellationToken token = default(CancellationToken));
Task<PatchOperation.Result<TEntity>> SendAsync<TEntity>(PatchOperation<TEntity> operation,
    CancellationToken token = default(CancellationToken));

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 
IMaintenanceOperation 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
IMaintenanceOperation<IndexStats> indexStatsOp = new GetIndexStatisticsOperation("Orders/ByCompany");
IndexStats indexStats =  documentStore.Maintenance.Send(indexStatsOp);
IndexRunningStatus status = indexStats.Status; // will be "Paused"
// Define operation, e.g. stop an index 
IMaintenanceOperation stopIndexOp = new StopIndexOperation("Orders/ByCompany");

// Execute the operation by passing the operation to Maintenance.Send
await documentStore.Maintenance.SendAsync(stopIndexOp);

// This specific operation returns void
// You can send another operation to verify the index running status
IMaintenanceOperation<IndexStats> indexStatsOp = new GetIndexStatisticsOperation("Orders/ByCompany");
IndexStats indexStats =  await documentStore.Maintenance.SendAsync(indexStatsOp);
IndexRunningStatus status = indexStats.Status; // will be "Paused"

Send syntax:

// Available overloads:
void Send(IMaintenanceOperation operation);
TResult Send<TResult>(IMaintenanceOperation<TResult> operation);
Operation Send(IMaintenanceOperation<OperationIdResult> operation);
// Available overloads:
Task SendAsync(IMaintenanceOperation operation,
    CancellationToken token = default(CancellationToken));
Task<TResult> SendAsync<TResult>(IMaintenanceOperation<TResult> operation,
    CancellationToken token = default(CancellationToken));
Task<Operation> SendAsync(IMaintenanceOperation<OperationIdResult> operation,
    CancellationToken token = default(CancellationToken));

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
IServerOperation<BuildNumber> getBuildNumberOp = new GetBuildNumberOperation();
    
// Execute the operation by passing the operation to Maintenance.Server.Send
BuildNumber buildNumberResult = documentStore.Maintenance.Server.Send(getBuildNumberOp);

// Access the operation result
int version = buildNumberResult.BuildVersion;
// Define operation, e.g. get the server build number
IServerOperation<BuildNumber> getBuildNumberOp = new GetBuildNumberOperation();
    
// Execute the operation by passing the operation to Maintenance.Server.Send
BuildNumber buildNumberResult = await documentStore.Maintenance.Server.SendAsync(getBuildNumberOp);

// Access the operation result
int version = buildNumberResult.BuildVersion;

Send syntax:

// Available overloads:
void Send(IServerOperation operation);
TResult Send<TResult>(IServerOperation<TResult> operation);
Operation Send(IServerOperation<OperationIdResult> operation);
// Available overloads:
Task SendAsync(IServerOperation operation,
    CancellationToken token = default(CancellationToken));
Task<TResult> SendAsync<TResult>(IServerOperation<TResult> operation,
    CancellationToken token = default(CancellationToken));
Task<Operation> SendAsync(IServerOperation<OperationIdResult> operation,
    CancellationToken token = default(CancellationToken));

The following server-maintenance operations are available:


Wait for completion

  • Some operations may take a long time to complete.
    Those operations will run in the server background and can be awaited for completion.
  • The response of the inner 'RavenCommand' class for such operations is OperationIdResult.
  • For those operations, the Send method will return an Operation object that allows waiting on that operation Id.

Example:

// Define operation, e.g. delete all discontinued products 
// Note: This operation implements: 'IOperation<OperationIdResult>'
IOperation<OperationIdResult> deleteByQueryOp =
    new DeleteByQueryOperation("from Products where Discontinued = true");
    
// Execute the operation
// Send returns an 'Operation' object that can be awaited on
Operation operation = documentStore.Operations.Send(deleteByQueryOp);

// Call method 'WaitForCompletion' to wait for operation completion 
BulkOperationResult result = (BulkOperationResult)operation.WaitForCompletion(TimeSpan.FromMinutes(2));

// Access the operation result
long numberOfItemsDeleted = result.Total;
// Define operation, e.g. delete all discontinued products
// Note: This operation implements: 'IOperation<OperationIdResult>'
IOperation<OperationIdResult> deleteByQueryOp =
    new DeleteByQueryOperation("from Products where Discontinued = true");
    
// Execute the operation
// SendAsync returns an 'Operation' object that can be awaited on
Operation operation = await documentStore.Operations.SendAsync(deleteByQueryOp);

// Call method 'WaitForCompletionAsync' to wait for operation completion 
BulkOperationResult result = 
    await operation.WaitForCompletionAsync(TimeSpan.FromMinutes(2))
                   .ConfigureAwait(false) as BulkOperationResult;

// Access the operation result
long numberOfItemsDeleted = result.Total;

Syntax:

// Available overloads:
public IOperationResult WaitForCompletion(TimeSpan? timeout = null)

public TResult WaitForCompletion<TResult>(TimeSpan? timeout = null)
    where TResult : IOperationResult
// Available overloads:
public Task<IOperationResult> WaitForCompletionAsync(TimeSpan? timeout = null)

public async Task<TResult> WaitForCompletionAsync<TResult>(TimeSpan? timeout = null)
    where TResult : IOperationResult
Parameters Type Description
timeout TimeSpan
  • When timespan is specified -
    server throws an error if operation has Not completed within the specified time frame. No rollback action will take place.
  • null -
    WaitForCompletion will wait for operation to complete forever.
Return type
IOperationResult The operation result content.