Operations: How to Delete Documents by Query

DeleteByQueryOperation gives you the ability to delete a large number of documents with a single query. This operation is performed in the background on the server.

Syntax

DeleteByQueryOperation DeleteByQueryOperation<TEntity, TIndexCreator>(
    Expression<Func<TEntity, bool>> expression,
    QueryOperationOptions options = null)
    where TIndexCreator : AbstractIndexCreationTask, new();

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

DeleteByQueryOperation DeleteByQueryOperation(
    IndexQuery queryToDelete, QueryOperationOptions options = null);
Parameters Type Description
indexName string Name of an index to perform a query on
expression Expression<Func<T, bool>> The LINQ expression (the query that will be performed)
queryToDelete IndexQuery Holds all the information required to query an index
options QueryOperationOptions Holds different setting options for base operations

Example I

// remove all documents from the server where Name == Bob using Person/ByName index
var operation = store
    .Operations
    .Send(new DeleteByQueryOperation<Person>("Person/ByName", x => x.Name == "Bob"));
// remove all documents from the server where Name == Bob using Person/ByName index
var operation = await store
    .Operations
    .SendAsync(new DeleteByQueryOperation<Person>("Person/ByName", x => x.Name == "Bob"));
from index 'Person/ByName' where Name = 'Bob'

Example II

// remove all documents from the server where Age > 35 using Person/ByAge index
var operation = store
    .Operations
    .Send(new DeleteByQueryOperation<Person, Person_ByAge>(x => x.Age < 35));
//remove all documents from the server where Age > 35 using Person/ByAge index
var operation = await store
    .Operations
    .SendAsync(new DeleteByQueryOperation<Person, Person_ByAge>(x => x.Age < 35));
from index 'Person/ByName' where Age < 35

Example III

// delete multiple docs with specific ids in a single run without loading them into the session
var operation = store
    .Operations
    .Send(new DeleteByQueryOperation(new IndexQuery
    {
        Query = "from People u where id(u) in ('people/1-A', 'people/3-A')"
    }));
// delete multiple docs with specific ids in a single run without loading them into the session
var operation = await store
    .Operations
    .SendAsync(new DeleteByQueryOperation(new IndexQuery
    {
        Query = "from People u where id(u) in ('people/1-A', 'people/3-A')"
    }));
from People u where id(u) in ('people/1-A', 'people/3-A')

WaitForCompletion

DeleteByQueryOperation is performed in the background on the server.
You have the option to wait for it using WaitForCompletion.

// remove all document from server where Name == Bob and Age >= 29 using People collection
var operation = store
    .Operations
    .Send(new DeleteByQueryOperation(new IndexQuery
    {
        Query = "from People where Name = 'Bob' and Age >= 29"
    }));

operation.WaitForCompletion(TimeSpan.FromSeconds(15));
// remove all document from server where Name == Bob and Age >= 29 using People collection
var operation = await store
    .Operations
    .SendAsync(new DeleteByQueryOperation(new IndexQuery
    {
        Query = "from People where Name = 'Bob' and Age >= 29"
    }));

await operation.WaitForCompletionAsync(TimeSpan.FromSeconds(15));
from People where Name = 'Bob' and Age >= 29

Remarks

Map only indexes

DeleteByQueryOperation can only be performed on a map index. Executing it on map-reduce index will lead to an exception.

Batching and Concurrency

The deletion of documents matching a specified query is run in batches of size 1024. RavenDB doesn't do concurrency checks during the operation so it can happen than a document has been updated or deleted meanwhile.