RavenDB 4.1 FeaturesThis document is included in your subscription
Subscriptions in RavenDB allow you to build persistent queries, batch operations and respond immediately to changes in your data. You can read more about them in this post, and I have dedicated a full chapter to discussing them in the book.
In RavenDB 4.1 we improved subscription support by adding the ability to include related documents directly as part of the subscription. Consider the following subscription:
The output of this subscription is going to be orders where the geographical coordinates of the subscriptions are not known. We use that to enrich the data by adding the missing location data from the shipping address. This is important for features such as spatial searches, planning deliveries, etc. For the purpose of this post, we’ll assume that we accept user’s addresses, which do not have spatial information on them and we use a background process to fill them in.
On the one hand, we do want to add the location data as soon as possible but on the other hand, we want to avoid making too many address resolution requests, to avoid having to pay for them. Here is what we come up with to resolve this.
You can see that there are a bunch of interesting things in this code:
- We can access the related company on the order using Load, and it will not trigger any network call.
- If the company already has this address, we can use the known location, without having to make an expensive geo-location call.
- If the company doesn’t have an address, we’ll fill this in for the next run.
- If the company’s address doesn’t have location, only then we’ll make a remote call to get the actual location data.
- We don’t call Store() anywhere, because we are using the session instance from the batch, when we call SaveChanges(), all the changes to the loaded documents (either orders or companies) will be saved as a single transaction.
- Because we update the Location field on the order, we won’t be called again with the updated order, since the subscription filters this.
All in all, this is a pretty neat way to handle the scenario in a very efficient manner.
More posts in "RavenDB 4.1 Features" series:
- (22 Aug 2018) MongoDB & CosmosDB Migration Wizards
- (04 Jul 2018) This document is included in your subscription
- (03 Jul 2018) Detailed query timing details
- (02 Jul 2018) Of course I know ya, dude
- (29 Jun 2018) Running RavenDB embedded
- (26 Jun 2018) Can you explain that choice?
- (20 Jun 2018) Cluster wide ACID transactions
- (19 Jun 2018) Explain that choice
- (22 May 2018) Highlighting
- (11 May 2018) Counting my counters
- (10 May 2018) JavaScript Indexes
- (04 May 2018) SQL Migration Wizard
Comments
Nice. We actually have something like this at 3M - updating geolocations for entities whose address were input by users. But we're using .Changes in an older Raven 3 app. And we have to manually load the company there.
Subscriptions with includes will be a nice fit here for us when we move to 4.0.
How can I specify collection name in 'include' clause in case field contains id but its name doesn't reflect collection name. Can I specify collection name in explicit way?
David, You can use a
declare function
to do more custom operations, so you'll call a function from the select that would callinclude
and apply your logic. See : https://github.com/ravendb/ravendb/blob/v4.1/test/SlowTests/Issues/RavenDB-11166.cs#L96Just realized that you use convention for IDs as "employees/1-A" ... that helps identify target collection and find document easily. Very nice. My question was related to fact, that we imported (into RavenDB) our 500K documents MongoDB database (btw. your migration tool is powerfull and imported about 20 MongoDB collections easily) where we use UUID based IDs. Btw. RavenDB seems excelent product. We are in phase of evaluating it as replacement for our current stack = MongoDB + Elasticsearch. It seems that we can replace both with just one RavenDB :-)
David, You can modify the documents as they are being sent over. We find that given the document meaningful names and numbers is much easier to understand. With guids as the ID, you don't really have any way to look at a document id and know what it means. With the default convention, you can actually talk about
employee #33
and it make sense.Comment preview