Anchoring Documents to a Bucket



Overview

  • Anchoring documents to a bucket is done by appending a suffix to the document ID.
    You cannot explicitly select a bucket by number; instead, the bucket is determined based on the suffix used.
    The suffix is composed of the $ symbol + your choice of suffix-text.

  • RavenDB will run the hashing algorithm only over the ID part following the $ symbol to determine which bucket the document will be placed in. If a document ID contains multiple $ symbols, only the suffix following the last $ will be used to calculate the bucket number.

  • Documents whose IDs end with the same suffix, will share the same bucket (and therefore a shard).

Avoid anchoring too many documents to the same bucket to prevent creating an oversized bucket
that cannot be split and resharded if needed to balance the database.

Anchor multiple documents to the same bucket as a specific document

  • To store a document in the same bucket as another specific document,
    use the following format for the new document's ID:
    <new document ID> + $ + <ID of the document you want to anchor it with>
    The new anchored document will be stored in the same bucket as that other document.

  • For example, creating a document with the following ID: <Users/70> + $ + <Users/4>
    will place document Users/70$Users/4 in the same bucket as Users/4.

    "Anchored Documents"

    "Users/70$Users/4" is stored in the same bucket as "Users/4"

  • An anchored document is accessible only by its full name.
    E.g., Users/70 and Users/70$Users/4 are two different documents,
    where Users/70$Users/4 is anchored to Users/4 and Users/70 is not.

  • It is possible to anchor multiple documents to the same document.
    E.g., naming three documents Users/70$Users/4, Users/71$Users/4, and Users/72$Users/4
    will make the database store these documents in the same bucket as Users/4.

Anchor multiple documents using a common suffix

  • It is possible to anchor multiple documents to the same bucket using an arbitrary suffix that does not correspond
    to an existing document.

  • E.g., Users/1$foo and Users/2$foo will be stored in the same bucket.

Examples

Example 1

Explicitly store a document with another document's name as a suffix, to keep both documents in the same bucket.
In this case, keep an invoice in the same bucket as its order.

// The invoice will be stored with the order ID as a suffix
session.Store(invoice, invoice.Id + "$" + order.Id);
session.SaveChanges();

Example 2

Define and use a naming convention for invoices.
Whenever an invoice is stored, the $ symbol and an order ID are automatically added to the invoice's ID
to assure that invoices and orders are kept in the same bucket.

// Store an invoice document in the same bucket as its order document

// Define a naming convention for invoices
// When an invoice is stored, the $ symbol and an order ID will be added to the invoice ID
var conventions = new DocumentConventions();
conventions.RegisterAsyncIdConvention<Invoice>(async (dbName, r) =>
{
    var id = await conventions.AsyncDocumentIdGenerator(dbName, r);
    return $"{id}${r.OrderId}";
});

// Deploy the naming convention defined above
using (var store = new DocumentStore()
{
    Urls = new[] { "http://127.0.0.1:8080" },
    Database = "Products",
    Conventions = conventions
}.Initialize())
{
    using (var session = store.OpenSession())
    {
        var order = new Order();
        session.Store(order);
        
        // The invoice will be stored with the order ID as a suffix
        var invoice = new Invoice { OrderId = order.Id };
        session.Store(invoice);
        
        session.SaveChanges();
    } 
}