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 run 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.

  • In this page:

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.
// 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.SendAsync
var result = await store.Operations.SendAsync(deleteByQueryOp);

// All documents in collection 'Orders' will be deleted from the server.
from "Orders"

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).
// 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.SendAsync
var result = await store.Operations.SendAsync(deleteByQueryOp);

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

// * Since a dynamic query was made with a filtering condition,
//   an auto-index is generated (if no other matching auto-index already exists).
from "Orders" where Freight > 30

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.
// Define the delete by query operation
var deleteByQueryOp = new DeleteByQueryOperation(new IndexQuery
{
    // Provide an RQL querying the index
    Query = "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.
// Define the delete by query operation
var deleteByQueryOp =
    // Pass parameters:
    // * The index name
    // * A filtering expression on the index-field
    new DeleteByQueryOperation<Products_ByPrice.IndexEntry>("Products/ByPrice", x => x.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.
// Define the delete by query operation
var deleteByQueryOp =
    // Pass param:
    // * A filtering expression on the index-field
    new DeleteByQueryOperation<Products_ByPrice.IndexEntry, Products_ByPrice>(x => x.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.
from index "Products/ByPrice" where Price > 10

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"];
// 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 = await store.Operations.SendAsync(deleteByQueryOp);

// Wait for operation to complete
BulkOperationResult result = 
    await operation.WaitForCompletionAsync<BulkOperationResult>(TimeSpan.FromSeconds(15))
        .ConfigureAwait(false);

// * 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"];
from index "Products/ByPrice" where Price > 10
  • 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();

Parameter Type Description
queryToDelete string The RQL query to perform
queryToDelete IndexQuery Holds all the information required to query an index
indexName string The name of the index queried
expression Expression<Func<T, bool>> The expression that defines the query criteria
options QueryOperationOptions Object 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; }
}