Data Subscriptions: Common Data Subscription Creation Examples
- In this page:
- Create subscription on all documents in a collection
- Create subscription with filtering
- Create subscription with filtering and projection
- Create subscription with load document in filter projection
- Create subscription with include statement
- Create revisions enabled subscription
- Update existing subscription
Create subscription on all documents in a collection
Here we create a plain subscription on the Orders collection, without any constraint or transformation.
- Generic-syntax
- RQL-syntax
name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions<Order>
{
Name = "OrdersProcessingSumbscription"
});
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.
- Generic-syntax
- RQL-syntax
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.
- Generic-syntax
- RQL-syntax
name = store.Subscriptions.Create(
new SubscriptionCreationOptions<Order>()
{
Filter = x => x.Lines.Sum(line => line.PricePerUnit * line.Quantity) > 100,
Projection = x => new
{
Id = x.Id,
Total = x.Lines.Sum(line => line.PricePerUnit * line.Quantity)
}
});
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){
return {
Id: order.Id,
Total: getOrderLinesSum(order)
};
}
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.
- Generic-syntax
- RQL-syntax
name = store.Subscriptions.Create(
new SubscriptionCreationOptions<Order>()
{
Filter = x => x.Lines.Sum(line => line.PricePerUnit * line.Quantity) > 100,
Projection = 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 = load(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 include statement
Here we create a subscription on the collection Orders, which returns the orders and brings along all products mentioned in the order as included documents. See the usage example here.
Include statements can be added to a subscription in the raw RQL, or with the ISubscriptionIncludeBuilder
.
The subscription include builder is assigned to the option Includes in SubscriptionCreationOptions<T>
(see subscription API overview). It
supports methods for including documents as well as counters. These methods can be chained.
In raw RQL, include statements come in two forms, like in any other RQL statements:
- Include statement in the end of the query, starting with the
include
keyword, followed by paths to the field containing the IDs of the documents to include.
If projection is performed, the mechanism will look for the paths in the projected result, rather then the original document.
It is recommended to prefer this approach when possible both because of clarity of the query and slightly better performance. - Include function call inside a 'declared' function.
- Builder-syntax
- RQL-path-syntax
- RQL-javascript-syntax
store.Subscriptions.Create(new SubscriptionCreationOptions<Order>()
{
Includes = builder => builder
.IncludeDocuments(x => x.Lines.Select(y => y.Product))
});
store.Subscriptions.Create(new SubscriptionCreationOptions()
{
Query = @"from Orders include Lines[].Product"
});
store.Subscriptions.Create(new SubscriptionCreationOptions()
{
Query = @"
declare function includeProducts(doc)
{
doc.IncludedFields=0;
doc.LinesCount = doc.Lines.length;
for (let i=0; i< doc.Lines.length; i++)
{
doc.IncludedFields++;
include(doc.Lines[i].Product);
}
return doc;
}
from Orders as o select includeProducts(o)"
});
Including Counters
ISubscriptionIncludeBuilder
has three methods for including counters:
// Include a single counter
ISubscriptionIncludeBuilder<T> IncludeCounter(string name);
// Include multiple counters
ISubscriptionIncludeBuilder<T> IncludeCounters(string[] names);
// Include ALL counters from ALL documents that match the subscription criteria
ISubscriptionIncludeBuilder<T> IncludeAllCounters();
IncludeCounter
is used to specify a single counter, and IncludeCounters
for multiple counters. IncludeAllCounters
retrieves all counters from all subscribed documents.
Parameters | Type | Description |
---|---|---|
name | string | The name of a counter. The subscription will include all counters with this name that are contained in the documents the subscription retrieves. |
names | string[] | Array of counter names. |
In this example, we create a subscription that uses all three methods to include counters. This demonstrates
how the methods can be chained (needless to say, calling IncludeAllCounters()
makes the other two methods
redundant).
subscriptionName = store.Subscriptions.Create<Order>(new SubscriptionCreationOptions<Order>()
{
Includes = builder => builder
// Values for the specified counters will be included in the batch
.IncludeCounters(new[] { "Pros", "Cons" })
});
Create revisions enabled subscription
Here we create a subscription on Orders collection, which returns current and previous version of the subscriptions. Please see the page dedicated to subscriptions with revisions for more details and examples.
- Generic-syntax
- RQL-syntax
name = store.Subscriptions.Create(
new SubscriptionCreationOptions<Revision<Order>>());
name = await store.Subscriptions.CreateAsync(new SubscriptionCreationOptions()
{
Query = @"From Orders (Revisions = true)"
});
Update existing subscription
Here we update the filter query of an existing data subscription named "my subscription".
subscriptionName = store.Subscriptions.Update(new SubscriptionUpdateOptions()
{
// Specify the subscription you wish to modify
Name = "my subscription",
// Provide a new query
Query = "from Products where PricePerUnit > 50"
});
In addition to names, subscriptions also have a subscription ID on the server side. The
ID can be used to identify the subscription instead of using its name. This allows use to change
an existing subscription's name by specifying the subscription with the ID, and submitting
a new string in the Name
field of the SubscriptionUpdateOptions
.
// Get the subscription's ID
SubscriptionState mySubscription = store.Subscriptions.GetSubscriptionState("my subscription");
long subscriptionId = mySubscription.SubscriptionId;
// Update the subscription
subscriptionName = store.Subscriptions.Update(new SubscriptionUpdateOptions()
{
Id = subscriptionId,
Query = "from Products where PricePerUnit > 50"
});