LibrarySites.Banner

Working with IDs in Sitecore xDB

MongoDB is used to collect data in the Sitecore Experience Database (xDB). MongoDB is not a difficult tool to use, but there are a few things that a newbie may struggle with. This post covers one of those: IDs and GUIDs.

Working with IDs and GUIDs requires an understanding of how they're stored in MongoDB. In addition to explaining this, this post also aims to provide some helpful tips to get you working with these values quickly and easily.

Spoiler alert: This post will explain why you will never get any results when you run the following query on MongoDB:

db.Contacts.find({_id:'{1F53415E-4DA0-42D9-9F2B-ACB921F697CB}'})

About GUIDs and IDs and MongoDB

For the purposes of this post GUIDs and IDs are the same thing. They are both 128-bit values that uniquely identify something. They are typically displayed in hexadecimal format. An example is {1F53415E-4DA0-42D9-9F2B-ACB921F697CB}.

(Technically it's probably accurate to say that in the MongoDB world GUID is the data type and an ID is a property on an object that is of the GUID type. In the Sitecore world ID is a wrapper around a GUID that makes it easier to compare values.)

A GUID is a value, not a string. You can't search for a GUID using a string representation of the value unless the system provides that functionality. And MongoDB doesn't provide that. So if you're looking for a document in MondoDB with the ID {1F53415E-4DA0-42D9-9F2B-ACB921F697CB} you can't do something like this:

db.Contacts.find({_id:'{1F53415E-4DA0-42D9-9F2B-ACB921F697CB}'})

This query includes nothing that tells MongoDB to treat the value as a GUID. You will never get any documents back.

Searching with GUIDs

So how do you build a search using a GUID? You have to convert the hexadecimal value using the following algorithm:

  1. Convert the GUID into a byte array
  2. Convert the byte array into a Base64 encoded string
  3. Create a BSON BinData value using the encoded string

The first two steps can be implemented using the following C# code:

var guid = Guid.Parse("{1F53415E-4DA0-42D9-9F2B-ACB921F697CB}");
var bytes = guid.ToByteArray();
var value = Convert.ToBase64String(bytes);  //value will be XkFTH6BN2UKfK6y5IfaXyw==

Within MongoDB you use the following to finish the final step:

db.Contacts.find({_id:new BinData(3, 'XkFTH6BN2UKfK6y5IfaXyw==')})

A solution for infrequent queries

If you're only searching using GUIDs infrequently it is probably easier to use a website like this to encode a hexadecimal value. This site will let you enter a hexadecimal value and click a button and it will give you the properly encoded value for your query.

A solution for frequent queries

If you're frequently querying MongoDB you are probably using a tool like Robomongo. With Robomongo you can write queries such as the following (after you make a couple of changes!):

db.Contacts.find({_id:CSUUID("{1F53415E-4DA0-42D9-9F2B-ACB921F697CB}")})

CSUUID is a function that converts the hexadecimal value into the properly encoded value. But before you can use this function you have to follow the steps explained on the Robomongo website. Here are a few tips if you're running Robomongo on Windows:

  • ~/.mongorc.js may not exist on your machine. The ~ refers to your USERPROFILE folder. You can find this value by opening a command prompt and entering echo %USERPROFILE%.
  • When you download the uuidhelpers.js file, you can put that file anywhere you want. I put mine in the same folder as the .mongorc.js file. But you must properly format the path. For example, the line I add to my .mongorc.js file is load("c:\\users\\adc\\uuidhelpers.js");
  • In the Robomongo menu make sure Options > Load .mongorc.js is selected

Common use case

A common use for this kind of querying is when you want to find a specific contact in xDB, especially your own contact. You can find your contact ID by looking at the Sitecore session cookie in your browser. Your contact ID is stored in the cookie named SC_ANALYTICS_GLOBAL_COOKIE. My cookie has the following value: 3b77cd933f014a0686ad8bb0c9e816f5|False

My cookie ID is 3b77cd933f014a0686ad8bb0c9e816f5. So I can find my contact in MongoDB by entering the following query into Robomongo:

db.Contacts.find({_id:CSUUID("3b77cd933f014a0686ad8bb0c9e816f5")})

(The CSUUID function is pretty inclusive in terms of the format of the hexadecimal value that is passed to it. It doesn't care whether curly-braces or dashes are used, and it's not case-sensitive.)

Conclusion

I find making the small changes described above make it much easier to be working directly in MongoDB. Let you know if you agree in the comments.