Skip to main content

Delete by Query Operation

  • Use DeleteByQueryOperation to delete a large number of documents that match the provided query in a single server call.

  • Dynamic behavior:
    The deletion of documents matching the specified query is performed in batches of size 1024.
    During the deletion process, documents that are added/modified after the delete operation has started
    may also be deleted if they match the query criteria.

  • Background operation:
    This operation is performed in the background on the server.
    If needed, you can wait for the operation to complete. See: Wait for completion.

  • Operation scope:
    DeleteByQueryOperation runs as a single-node transaction, not a cluster-wide transaction. As a result,
    if you use this operation to delete documents that were originally created using a cluster-wide transaction,
    their associated Atomic guards will Not be deleted.

  • In this article:

Delete by dynamic query

Delete all documents in a collection
// Define the delete by query operation, pass an RQL querying a collection
var deleteByQueryOp = new DeleteByQueryOperation("from 'Orders'");

// Execute the operation by passing it to Operations.Send
var operation = store.Operations.Send(deleteByQueryOp);

// All documents in collection 'Orders' will be deleted from the server.
Delete with filtering
// Define the delete by query operation, pass an RQL querying a collection
var deleteByQueryOp = new DeleteByQueryOperation("from 'Orders' where Freight > 30");

// Execute the operation by passing it to Operations.Send
var operation = store.Operations.Send(deleteByQueryOp);

// * All documents matching the specified RQL will be deleted from the server.

// * Since the dynamic query was made with a filtering condition,
// an auto-index is generated (if no other matching auto-index already exists).

Delete by index query

  • DeleteByQueryOperation can only be performed on a Map-index.
    An exception is thrown when executing the operation on a Map-Reduce index.

  • A few overloads are available, see the following examples:

A sample Map-index
// The index definition:
// =====================

public class Products_ByPrice : AbstractIndexCreationTask<Product>
{
public class IndexEntry
{
public decimal Price { get; set; }
}

public Products_ByPrice()
{
Map = products => from product in products
select new IndexEntry
{
Price = product.PricePerUnit
};
}
}
Delete documents via an index query
// Define the delete by query operation, pass an RQL querying the index
var deleteByQueryOp =
new DeleteByQueryOperation("from index 'Products/ByPrice' where Price > 10");

// Execute the operation by passing it to Operations.Send
var operation = store.Operations.Send(deleteByQueryOp);

// All documents with document-field PricePerUnit > 10 will be deleted from the server.
Delete with options
// Define the delete by query operation
var deleteByQueryOp = new DeleteByQueryOperation(
// QUERY: Specify the query
new IndexQuery
{
Query = "from index 'Products/ByPrice' where Price > 10"
},
// OPTIONS: Specify the options for the operation
// (See all other available options in the Syntax section below)
new QueryOperationOptions
{
// Allow the operation to operate even if index is stale
AllowStale = true,
// Get info in the operation result about documents that were deleted
RetrieveDetails = true
});

// Execute the operation by passing it to Operations.Send
Operation operation = store.Operations.Send(deleteByQueryOp);

// Wait for operation to complete
var result = operation.WaitForCompletion<BulkOperationResult>(TimeSpan.FromSeconds(15));

// * All documents with document-field PricePerUnit > 10 will be deleted from the server.

// * Details about deleted documents are available:
var details = result.Details;
var documentIdThatWasDeleted = details[0].ToJson()["Id"];
  • Specifying QueryOperationOptions is also supported by the other overload methods, see the Syntax section below.

Syntax

// Available overload:
// ===================

DeleteByQueryOperation DeleteByQueryOperation(
string queryToDelete);

DeleteByQueryOperation DeleteByQueryOperation(
IndexQuery queryToDelete,
QueryOperationOptions options = null);

DeleteByQueryOperation DeleteByQueryOperation<TEntity>(
string indexName,
Expression<Func<TEntity, bool>> expression,
QueryOperationOptions options = null);

DeleteByQueryOperation DeleteByQueryOperation<TEntity, TIndexCreator>(
Expression<Func<TEntity, bool>> expression,
QueryOperationOptions options = null)
where TIndexCreator : AbstractIndexCreationTask, new();
ParameterTypeDescription
queryToDeletestringThe RQL query to perform
queryToDeleteIndexQueryHolds all the information required to query an index
indexNamestringThe name of the index queried
expressionExpression<Func<T, bool>>The expression that defines the query criteria
optionsQueryOperationOptionsObject holding different setting options for the operation
public class QueryOperationOptions
{
// Indicates whether operations are allowed on stale indexes.
// DEFAULT: false
public bool AllowStale { get; set; }

// If AllowStale is set to false and index is stale,
// then this is the maximum timeout to wait for index to become non-stale.
// If timeout is exceeded then exception is thrown.
// DEFAULT: null (if index is stale then exception is thrown immediately)
public TimeSpan? StaleTimeout { get; set; }

// Limits the number of base operations per second allowed.
// DEFAULT: no limit
public int? MaxOpsPerSecond

// Determines whether operation details about each document should be returned by server.
// DEFAULT: false
public bool RetrieveDetails { get; set; }

// Ignore the maximum number of statements a script can execute.
// Note: this is only relevant for the PatchByQueryOperation.
public bool IgnoreMaxStepsForScript { get; set; }
}