Find docs with no PartitionKey in Azure DocumentDb
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.
Many thanks to Aravind Ramachandran for telling me about 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()and you then try to save an instance of a class that looks like this:
{
Id = this.collectionName
};
docCollection.PartitionKey.Paths.Add("/partitionKey");
await docClient.CreateDocumentCollectionAsync(
UriFactory.CreateDatabaseUri(this.dbName),
docCollection);
public class MyItemthen 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.
{
[JsonProperty("id")]
public string Id { get; set; }
public string SomeValue { get; set; }
}
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) });