A notice to our customers: Microsoft are experiencing disruption related to several of their M365 services that could impact your system. We are carefully monitoring the situation. You can be kept updated via Microsoft's service page.
×

Find docs with no PartitionKey in Azure DocumentDb

06 December 2016 By Frans Lytzen
When you are using Partitioned Collections in Azure DocumentDb you need to specify a Partition Key on each Document. At least, I thought you did. But, it turns out that you actually can save documents without a partitionkey. But if you do, you'll have a hard time retrieving or deleting them - until you meet Undefined.Value.
Note: This post is written for C#, I am not sure about the equivalent for other languages.


Details

If you create a Partitioned Collection in Azure DocumentDb you probably think that every document you save must have a partitionkey property and probably also that it must have a value. In this post I am dealing with the situation where you don't have a partition key property on your document at all, not the situation where you have one but you set it to null or an empty string.

For example, if you have created your collection with code similar to this;
var docCollection = new DocumentCollection()
{
Id = this.collectionName
};
docCollection.PartitionKey.Paths.Add("/partitionKey");
await docClient.CreateDocumentCollectionAsync(
UriFactory.CreateDatabaseUri(this.dbName),
docCollection);
and you then try to save an instance of a class that looks like this:
public class MyItem
{
[JsonProperty("id")]
public string Id { get; set; }

public string SomeValue { get; set; }
}
then you may expect to get an error. But, in fact, it will save just fine as I found out to my detriment after a major refactoring.

Now that you have that item in the database you will find it hard to retrieve it and even harder to delete it - until you meet your new friend Undefined.Value.

How to read the document:

MyItem item = (dynamic)client.ReadDocumentAsync(
UriFactory.CreateDocumentUri(DbName, CollectionName, id),
new RequestOptions() {
PartitionKey = new PartitionKey(Undefined.Value)
})
.Result.Resource;

How to delete the document:

client.DeleteDocumentAsync(
UriFactory.CreateDocumentUri(DbName, CollectionName, id),
new RequestOptions() { PartitionKey = new PartitionKey(Undefined.Value) });
Many thanks to Aravind Ramachandran for telling me about Undefined.Value.