see on GitHub

How to create a data subscription?

Subscriptions in their essence all defined by an RQL like query that describes both the filtering and the projection. For convenience, we've provided several ways to express that definition, we'll cover all of them in this page.

Common subscription creation examples

Create subscription on whole collection

Here we create a plain subscription on the Orders collection, without any constraint or transformation.
name = await store.Subscriptions.CreateAsync<Order>();
name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
{
    Query = "from Orders"
});

Create subscription with filtering

Here we create a subscription on Orders collection, which total order revenue is greater than 100.
name = await store.Subscriptions.CreateAsync<Order>(x =>
    x.Lines.Sum(line => line.PricePerUnit * line.Quantity) > 100);
name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
{
    Query = @"
                   declare function getOrderLinesSum(doc){
                       var sum = 0;
                       for (var i in doc.Lines) { sum += doc.Lines[i];}
                       return sum;
                   }
                   from Orders as o 
                   where getOrderLinesSum(o) > 100"
});

Create subscription with filtering and projection

Here we create a subscription on Orders collection, which total order revenue is greater than 100, and return only ID and total revenue.
name = store.Subscriptions.Create(
    new SubscriptionCreationOptions<Order>()
    {
        Filter = x => x.Lines.Sum(line => line.PricePerUnit * line.Quantity) > 100,
        Project = x => new
        {
            Id = x.Id,
            Total = x.Lines.Sum(line => line.PricePerUnit * line.Quantity),
            ShipTo = x.ShipTo,
            EmployeeName = RavenQuery.Load<Employee>(x.Employee).FirstName + " " +
                           RavenQuery.Load<Employee>(x.Employee).LastName
        }
    });
name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
{
    Query = @"
                   declare function getOrderLinesSum(doc){
                       var sum = 0;
                       for (var i in doc.Lines) { sum += doc.Lines[i];}
                       return sum;
                   }

                   declare function projectOrder(doc){
                       var employee = LoadDocument(doc.Employee);
                       return {
                           Id: order.Id,
                           Total: getOrderLinesSum(order),
                           ShipTo: order.ShipTo,
                           EmployeeName: employee.FirstName + ' ' + employee.LastName

                       };
                   }

                   from Orders as o 
                   where getOrderLinesSum(o) > 100
                   select projectOrder(o)"
});

Create subscription with load document in filter projection

Here we create a subscription on Orders collection, which total order revenue is greater than 100, and return ID, total revenue, shipping address and responsible employee name.
name = store.Subscriptions.Create(
    new SubscriptionCreationOptions<Order>()
    {
        Filter = x => x.Lines.Sum(line => line.PricePerUnit * line.Quantity) > 100,
        Project = x => new
        {
            Id = x.Id,
            Total = x.Lines.Sum(line => line.PricePerUnit * line.Quantity),
            ShipTo = x.ShipTo,
            EmployeeName = RavenQuery.Load<Employee>(x.Employee).FirstName + " " +
                           RavenQuery.Load<Employee>(x.Employee).LastName
        }
    });
name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
{
    Query = @"
                   declare function getOrderLinesSum(doc){
                       var sum = 0;
                       for (var i in doc.Lines) { sum += doc.Lines[i];}
                       return sum;
                   }

                   declare function projectOrder(doc){
                       var employee = LoadDocument(doc.Employee);
                       return {
                           Id: order.Id,
                           Total: getOrderLinesSum(order),
                           ShipTo: order.ShipTo,
                           EmployeeName: employee.FirstName + ' ' + employee.LastName

                       };
                   }

                   from Orders as o 
                   where getOrderLinesSum(o) > 100
                   select projectOrder(o)"
});

Create versioning enabled subscription

Here we create a subscription on Orders collection, which returns current and previous version of the subscriptions. Please see the versioning subscription dedicated page for more details.
name = store.Subscriptions.Create(
    new SubscriptionCreationOptions<Order>()
    {
        Filter = x => x.Lines.Sum(line => line.PricePerUnit * line.Quantity) > 100,
        Project = x => new
        {
            Id = x.Id,
            Total = x.Lines.Sum(line => line.PricePerUnit * line.Quantity),
            ShipTo = x.ShipTo,
            EmployeeName = RavenQuery.Load<Employee>(x.Employee).FirstName + " " +
                           RavenQuery.Load<Employee>(x.Employee).LastName
        }
    });
name = store.Subscriptions.Create(
    new SubscriptionCreationOptions<Revision<Order>>());

Advanced subscription creation options

'SubscriptionCreationOptions' allows to define several parameters that we didn't speak about yet:

  • Name - User defined name of the subscription: allows you to have a human readable identification of a subscription.
  • ChangeVecotr - Allows to define a change vector, from which the subscription will start processing. It might be useful for ad-hoc processes that need to process only recent changes in data, for that specific use, the field may receive a special value: "LastDocument", that will take the latest change vector in the machine.
  • MentorNode - Allows to define a specific node in the cluster that we want to treat the subscription. That's useful in cases when one server is preffered over other, either because of stronger hardware or closer geographic proximity to clients etc.

API overview

SubscriptionCreationOptions

Non generic version of the class, relies on user's full knowledge of the RQL query structure

Member Type Required Description
Name string N User defined name of subscription.
Query string Y RQL query that describes the subscription. That RQL comes with additional support to javascript clause inside the 'Where' statement and special semantics for subscriptions on documents revisions.
ChangeVector string N Name of database to create a data subscription. If null, default database configured in DocumentStore will be used.
MentorNode N string Node tag of the preffered node to run the subscription. If the node is down, the subscription Name of database to create a data subscription. If null, default database configured in DocumentStore will be used.

SubscriptionCreationOptions<T>

An RQL statement will be built based on the fields.

Member Type Required Description
<T> type Y Type of the object, from which the collection will be derived.
Name string N User defined name of subscription.
Filter Expression<Func<T, bool>> N Lambda describing filter logic for the subscription. Will be transalted to a javascript function.
Projection Expression<Func<T, object>> N Lambda describing the projection of returned documents. Will be translated to a javascript function
ChangeVector N string Name of database to create a data subscription. If null, default database configured in DocumentStore will be used.

IReliableSubscription.Create\CreateAsync overloads summary

All overload apply both to sync and async create variants.

Return value

Return value
string Created data subscription name. If Name was provided in SubscriptionCreationOptions, it will be returned, otherwise, a unique name will be generated by server.

Create(SubscriptionCreationOptions criteria, string database = null)

Parameters
options SubscriptionCreationOptions<T> Contains subscription creation options, must have at least "query" field
database string Name of database to create a data subscription. If null, default database configured in DocumentStore will be used.

Create<T>(SubscriptionCreationOptions<T> options, string database = null)

Parameters
options SubscriptionCreationOptions<T> Contains typed subscription creation options.
database string Name of database to create a data subscription. If null, default database configured in DocumentStore will be used.

Create<T>(Expression<Func<T, bool>> predicate = null, SubscriptionCreationOptions options = null, string database = null)

Parameters
predicate Expression<Func<T, bool>> Predicate that returns a boolean, describing filter of the subscription documents
options SubscriptionCreationOptions<T> Contains typed subscription creation options.
database string Name of database to create a data subscription. If null, default database configured in DocumentStore will be used.