DocumentDB is a NoSQL JSON database by Microsoft that is provided as a service in Azure. Due to its cloud service architecture, this allows developers and clients to read and write to the service using the DocumentDB API and have a globally scalable and lightning fast data repository. This provides a consumption-based NoSQL database and an alternative to xDB Cloud.
To help with the migration of existing MongoDB customers, Microsoft recently released the public preview of DocumentDB with MongoDB protocol support – essentially, Microsoft has provided DocumentDB support to interpret queries from MongoDB and have a transparent experience using DocumentDB with existing code intended for MongoDB. I had an opportunity to play with this in private preview earlier on in the year and the MongoDB support has really come into its own now that it’s in private preview.
So let’s put DocumentDB through its paces – we’re going to create a new DocumentDB instance with MongoDB protocol support and route our xDB interactions to it. We’re not going to make any changes to the existing Sitecore xDB code but will need to add a pipeline processor for TLS.
DISCLAIMER: Given that this is currently in preview, I wouldn’t recommend this as something to put into a production setting. Once it does go GA however, I would still recommend that you do some extensive testing before fully replacing a MongoDB instance with this. Don’t say I didn’t warn you.
First, we create a new instance of DocumentDB in Azure. Make sure you select the version that is labeled “Protocol Support for MongoDB”.
Once the database is created, you’ll be able to go into the blade and select “Connection String” from the menu. This will display all of the relevant information for your DocumentDB instance.
This is the connection string information you’ll need to update the analytics connection strings in Sitecore.
Before you do that, however, be aware that DocumentDB requires TLS 1.2 as its SSL protocol when accessing it through the MongoDB driver. Unfortunately, this is something that will need to be specified in code when using the MongoDB driver to initialize the connection. Fortunately, Sitecore provides a pipeline to modify those connection settings!
You’ll need to add a pipeline processor with the following code:
using System.Security.Authentication; using MongoDB.Driver; using Sitecore.Analytics.Pipelines.UpdateMongoDriverSettings; namespace GC.Sitecore.DocumentDB { public class InitializeTls12Processor : UpdateMongoDriverSettingsProcessor { public override void UpdateSettings(UpdateMongoDriverSettingsArgs args) { args.MongoSettings.SslSettings = new SslSettings {EnabledSslProtocols = SslProtocols.Tls12}; } } }
…and patch your config with that pipeline as so:
<configuration xmlns:patch="www.sitecore.net/xmlconfig"> <sitecore> <pipelines> <updateMongoDriverSettings> <processor type="GC.Sitecore.DocumentDB.InitializeTls12Processor, GC.Sitecore.DocumentDB" /> </updateMongoDriverSettings> </pipelines> </sitecore> </configuration>
If you don’t want to do all this manually, you can download a Sitecore package to handle all of this on my GitHub here:
https://github.com/georgechang/sitecore-xdb-documentdb-processor/releases/tag/1.0
This will enable TLS 1.2 for the xDB connection in Sitecore.
Now you can update your Sitecore analytics connection strings. You can pretty much copy and paste the connection string provided by the Azure portal and append the collection names. They should look something like this:
<add name="analytics" connectionString="mongodb://[username]:[password]@xdb.documents.azure.com:10250/sitecore_analytics?ssl=true" /> <add name="tracking.live" connectionString="mongodb://[username]:[username]@xdb.documents.azure.com:10250/sitecore_tracking_live?ssl=true" /> <add name="tracking.history" connectionString="mongodb://[username]:[password]@xdb.documents.azure.com:10250/sitecore_tracking_history?ssl=true" /> <add name="tracking.contact" connectionString="mongodb://[username]:[password]@xdb.documents.azure.com:10250/sitecore_tracking_contact?ssl=true" />
That’s it! Sitecore will automatically create the collections as it needs them and all your xDB data is now flowing into DocumentDB and will be processed from there as well.
For more information about DocumentDB and MongoDB protocol support, Microsoft provides documentation here:
https://azure.microsoft.com/en-us/documentation/articles/documentdb-protocol-mongodb/
Microsoft has renamed (since it\’s no longer in preview) to \”Database as a service for MongoDB\”. Very cool indeed. Great article George!
Trying this with 8.2 update 2, but having errors in the log files :
21244 09:26:28 ERROR Cannot create tracker.
Exception: System.Exception
Message: Exceeded max attempt count when trying to lock contact
Source: Sitecore.Analytics.MongoDB
at Sitecore.Analytics.Data.DataAccess.MongoDb.MongoDbContactStorage.TryLoadContact(ID contactId, String identifier, IContactFactory factory, LeaseOwner leaseOwner, TimeSpan leaseDuration, Int32 maxAttempts)
Hi George,
I have been getting the error below since following your guide which causes analytics and other functionally not to work. I am using the new Cosmos DB but with MongoDB API but this generally seem to be mostly what you were using before simply re-branded. I am using Sitecore 8.1 Update 1 which is one reason I could be running into this (Since I dont know which version of the MongoDB API Cosmos uses and 8.1 only officially supports up to 3.0). Lastly, the actual connection appears fine and collections were created but appears to have no data due to this error.
Any thoughts you have would be very helpful.
Exception: System.InvalidCastException
Message: Unable to cast object of type \’MongoDB.Bson.BsonInt32\’ to type \’MongoDB.Bson.BsonInt64\’.
Source: Sitecore.Analytics.MongoDB
at Sitecore.Analytics.RangeScheduler.MongoDbRangeMap2.BuildRangeRecord(BsonDocument document)
at Sitecore.Analytics.RangeScheduler.MongoDbRangeMap2.TryLockRange(WorkerHandle worker, DateTime leaseExpiration, RangeHandle& range)
at Sitecore.Analytics.Processing.RangeScheduler.RangeMapWorkScheduler3`1.TryLockRange(WorkScheduler`1& context)
at Sitecore.Analytics.Processing.RangeScheduler.RangeMapWorkScheduler3`1.GetNextRange(WorkScheduler`1& context, Boolean returning)
at Sitecore.Analytics.Processing.RangeScheduler.RangeMapWorkScheduler3`1.TryGetNext(ItemBatch`1& item)
at Sitecore.Analytics.Processing.WorkSchedulerWithBacklog`1.TryGetNext(ItemBatch`1& batch)
at Sitecore.Analytics.Aggregation.Data.Processing.InteractionBatchHistoryWorker.Execute()
at Sitecore.Analytics.Core.BackgroundService.Run()