Data Subscription Creation Examples
-
This page contains examples of creating a subscription.
To learn how to consume and process documents sent by the subscription, see these examples. -
For a detailed syntax of the available subscription methods and objects, see this API overview.
-
In this page:
- Create subscription - for all documents in a collection
- Create subscription - filter documents
- Create subscription - filter and project fields
- Create subscription - project data from a related document
- Create subscription - include documents
- Create subscription - include counters
- Create subscription - subscribe to revisions
- Create subscription - via update
- Update existing subscription
Create subscription - for all documents in a collection
Here we create a plain subscription on the Orders collection without any constraints or transformations.
The server will send ALL documents from the Orders collection to a client that connects to this subscription.
const subscriptionName = await documentStore.subscriptions.create({
// Optionally, provide a custom name for the subscription
name: "OrdersProcessingSubscription",
// You can provide the collection name in the RQL string in the 'query' param
query: "from Orders"
});
const subscriptionName = await documentStore.subscriptions.create({
name: "OrdersProcessingSubscription",
// Or, you can provide the document type for the collection in the 'documentType' param
documentType: Order
});
// Or, you can use the folllowing overload,
// pass the document class type to the 'create' method
const subscriptionName = await documentStore.subscriptions.create(Order);
Create subscription - filter documents
Here we create a subscription for documents from the Orders collection where the total order revenue is greater than 100. Only documents that match this condition will be sent from the server to a client connected to this subscription.
// Define the filtering criteria
const query = `
declare function getOrderLinesSum(doc) {
var sum = 0;
for (var i in doc.Lines) {
sum += doc.Lines[i].PricePerUnit * doc.Lines[i].Quantity;
}
return sum;
}
from Orders as o
where getOrderLinesSum(o) > 100`;
// Create the subscription with the defined query
const subscriptionName = await documentStore.subscriptions.create({ query });
// In this case, the server will create a default name for the subscription
// since no specific name was provided when creating the subscription.
Create subscription - filter and project fields
Here, again, we create a subscription for documents from the Orders collection where the total order revenue is greater than 100. However, this time we only project the document ID and the Total Revenue properties in each object sent to the client.
const query = `
declare function getOrderLinesSum(doc) {
var sum = 0;
for (var i in doc.Lines) {
sum += doc.Lines[i].PricePerUnit * doc.Lines[i].Quantity;
}
return sum;
}
declare function projectOrder(doc) {
return {
Id: doc.Id,
Total: getOrderLinesSum(doc)
}
}
from order as o
where getOrderLinesSum(o) > 100
select projectOrder(o)`;
const subscriptionName = await documentStore.subscriptions.create({ query });
Create subscription - project data from a related document
In this subscription, in addition to projecting the document fields,
we also project data from a related document that is loaded using the load
method.
const query = `
declare function getOrderLinesSum(doc) {
var sum = 0;
for (var i in doc.Lines) {
sum += doc.Lines[i].PricePerUnit * doc.Lines[i].Quantity;
}
return sum;
}
declare function projectOrder(doc) {
var employee = load(doc.Employee);
return {
Id: doc.Id,
Total: getOrderLinesSum(doc),
ShipTo: doc.ShipTo,
EmployeeName: employee.FirstName + ' ' + employee.LastName
}
}
from order as o
where getOrderLinesSum(o) > 100
select projectOrder(o)`;
const subscriptionName = await documentStore.subscriptions.create({ query });
Create subscription - include documents
Here we create a subscription on the Orders collection, which will send all the Order documents.
In addition, the related Product documents associated with each Order are included in the batch sent to the client. This way, when the subscription worker that processes the batch in the client accesses a Product document, no additional call to the server will be made.
See how to consume this type of subscription here.
const options = {
// The documents whose IDs are specified in the 'Product' property
// will be included in the batch
includes: builder => builder.includeDocuments("Lines[].Product"),
documentType: Order
};
const subscriptionName = await documentStore.subscriptions.create(options);
const query = `from Orders include Lines[].Product`;
const subscriptionName = await documentStore.subscriptions.create({ query });
const query = `
declare function includeProducts(doc) {
let includedFields = 0;
let linesCount = doc.Lines.length;
for (let i = 0; i < linesCount; i++) {
includedFields++;
include(doc.Lines[i].Product);
}
return doc;
}
from Orders as o select includeProducts(o)`;
const subscriptionName = await documentStore.subscriptions.create({ query });
Include using builder:
Include statements can be added to the subscription with a builder object.
This builder is assigned to the includes
property in the options object.
It supports methods for including documents as well as counters.
These methods can be chained.
See this API overview for all available include methods.
To include related documents, use method includeDocuments
.
(See the Builder-syntax tab in the example above).
Include using RQL:
The include statements can be written in two ways:
-
Use the
include
keyword at the end of the query, followed by the paths to the fields containing the IDs of the documents to include. It is recommended to prefer this approach whenever possible, both for the clarity of the query and for slightly better performance.
(See the RQL-path-syntax tab in the example above). -
Define the
include
within a JavaScript function that is called from theselect
clause.
(See the RQL-javascript-syntax tab in the example above).
If you include documents when making a projection, the include will search for the specified paths in the projected fields rather than in the original document.
Create subscription - include counters
Here we create a subscription on the Orders collection, which will send all the Order documents.
In addition, values for the specified counters will be included in the batch.
Note:
Modifying an existing counter's value after the document has been sent to the client does Not trigger re-sending.
However, adding a new counter to the document or removing an existing one will trigger re-sending the document.
const options = {
includes: builder => builder
// Values for the specified counters will be included in the batch
.includeCounters(["Pros", "Cons"]),
documentType: Order
};
const subscriptionName = await documentStore.subscriptions.create(options);
const options = {
query: "from Orders include counters('Pros'), counters('Cons')"
};
const subscriptionName = await documentStore.subscriptions.create(options);
All include methods can be chained:
For example, the following subscription includes multiple counters and documents:
const options = {
includes: builder => builder
.includeCounter("Likes")
.includeCounters(["Pros", "Cons"])
.includeDocuments("Employee"),
documentType: Order
};
const subscriptionName = await documentStore.subscriptions.create(options);
Create subscription - subscribe to revisions
Here we create a simple revisions subscription on the Orders collection that will send pairs of subsequent document revisions to the client.
const subscriptionName = await documentStore.subscriptions.createForRevisions({
documentType: Order
});
const subscriptionName = await documentStore.subscriptions.createForRevisions({
query: "from Orders (Revisions = true)"
});
Learn more about subscribing to document revisions in subscriptions: revisions support.
Create subscription - via update
When attempting to update a subscription that does Not exist,
you can request a new subscription to be created by setting createNew
to true
.
In such a case, a new subscription will be created with the provided query.
const subscriptionName = await documentStore.subscriptions.update({
name: "my subscription",
query: "from Products where PricePerUnit > 20",
// Set to true so that a new subscription will be created
// if a subscription with name "my subscription" does Not exist
createNew: true
});
Update existing subscription
Update subscription by name:
The subscription definition can be updated after it has been created.
In this example we update the filtering query of an existing subscription named "my subscription".
const subscriptionName = await documentStore.subscriptions.update({
// Specify the subscription you wish to modify
name: "my subscription",
// Provide a new query
query: "from Products where PricePerUnit > 50"
});
Update subscription by id:
In addition to the subscription name, each subscription is assigned a subscription ID when it is created by the server.
This ID can be used instead of the name when updating the subscription.
// Get the subscription's ID
const mySubscription = await documentStore.subscriptions.getSubscriptionState("my subscription");
const subscriptionId = mySubscription.subscriptionId;
// Update the subscription
const subscriptionName = await documentStore.subscriptions.update({
id: subscriptionId,
query: "from Products where PricePerUnit > 50"
});
Using the subscription ID allows you to modify the subscription name:
// Get the subscription's ID
const mySubscription = await documentStore.subscriptions.getSubscriptionState("my subscription");
const subscriptionId = mySubscription.subscriptionId;
// Update the subscription's name
const subscriptionName = await documentStore.subscriptions.update({
id: subscriptionId,
name: "new name"
});