Revisions: Including Revisions



Including Revisions

When it is known prior to the retrieval of a document that its revisions may be needed, the revisions can be Included so they'd be loaded along with the document without requiring additional trips to the server.

When the document is loaded, Loading any of its included revisions will retrieve them from memory rather than from the server.

This may be useful when, for example, a document that contains financial data is loaded by an auditing application. The document's past revisions can be included with the document, to make the document's history available for instant inspection.

Revisions can be Included by their Creation Time or Change Vector.


Including Revisions By Time

To include a single revision by its creation time -
Pass a DateTime value to Session.Load or Session.Query using IncludeRevisions (see below),
or to a Raw Query using .AddParameter.

  • If the provided time matches the creation time of a document revision, this revision will be included.
  • If no exact match is found, the nearest revision to precede it will be included.
    • E.g. -
      If the time you provided is April 7 2020,
      and it is located between two existing revisions dated April 2 2020 and April 11 2020,
      the April 2 revision will be included.
  • If no revisions exist RavenDB will remember it, and when you ask for the revision it will skip the trip to the server and return null.

Including Revisions By Change Vector

Each time a document is modified, its Change Vector is revised to trigger the document's replication, backup, etc.
While the Revisions feature is enabled, each new document revision keeps the document's change vector at the time of its creation.
We can use this to track and include Single or Multiple document revisions by their change vectors.
To do so:

  1. Store helpful change vectors in advance, in a property of the document.
  2. When you want to include revisions by their change vector -
    Pass the path to the document property to Session.Load or Session.Query via IncludeRevisions (see below),
    or to a Raw Query using .AddParameter.

Storing a document's change vector/s in one of the document's properties helps clarify their context and purpose.
E.g. -
A change vector can be added to an employee's contract document's "ContractRev" property each time the contract is revised (e.g. when their salary is raised).
Whenever the time comes to re-evaluate this employee's terms and their contract is loaded, its past revisions can be easily included with it by their change vectors.


IncludeRevisions

Revisions can be included with documents retrieved via Session.Load and Session.Query, using one of the IncludeRevisions methods.

// Include a single revision by Time
TBuilder IncludeRevisions(DateTime before);
// Include a single revision by Change Vector
TBuilder IncludeRevisions(Expression<Func<T, string>> path);
// Include an array of revisions by Change Vectors
TBuilder IncludeRevisions(Expression<Func<T, IEnumerable<string>>> path);
Parameters Type Description
before DateTime A single revision that matches or precedes the given time will be included.
path Expression<Func<T, string>> A path to a document property that contains a single change vector.
The revision whose change vector is contained in the document property will be Included.
path Expression<Func<T, IEnumerable<string>>> A path to a document property that contains an array of change vectors.
The revisions whose change vectors are contained in the array will be Included.

Including Revisions With Session.Load

Load: Include Revisions by Time

To include a single revision by its creation time, pass IncludeRevisions the time.
The revision whose creation time matches or immediately precedes that of the given time will be included.

// Pass `IncludeRevisions` a `DateTime` value
var query = session.Load<User>(id, builder => builder
    .IncludeRevisions(creationTime.ToUniversalTime()));

// The revision has been included by its creation time,
// and is now retrieved locally from the session
var revision = session
    .Advanced.Revisions.Get<User>(id, creationTime.ToUniversalTime());

Load: Include Revisions by Change Vector

  • To include a single revision by a document's change vector:
    Pass IncludeRevisions the path to a property of the document you load, that contains the change vector.

  • To include a group of revisions by their change vectors:
    Pass IncludeRevisions the path to a property of the document you load, that contains an array of change vectors.

  • Sample:

    var sn = session.Load<Contract>(id, builder => builder
        // Include a single revision 
        .IncludeRevisions(x => x.ContractRev_1_ChangeVector)
        // Include a group of revisions
        .IncludeRevisions(x => x.ContractRevChangeVectors));
    
    // The revisions have been included by change vectors,
    // and are now retrieved locally from the session
    var revision = sn.ContractRev_1_ChangeVector;
    var revisions = sn.ContractRevChangeVectors;
    Contract:
    private class Contract
    {
        public string Name { get; set; }
        
        // A single revision's Change Vector
        public string ContractRev_1_ChangeVector { get; set; }
    
        // A single revision's Change Vector
        public string ContractRev_2_ChangeVector { get; set; }
    
        // An array of revision Change Vectors
        public List<string> ContractRevChangeVectors { get; set; }
    }

Including Revisions With Session.Query

  • To include a revision by time, pass IncludeRevisions a DateTime value.
  • To include a single revision or a group of revisions by change vectors, pass IncludeRevisions a path to a property of the loaded document, that stores change vectors.

Query: Include Revisions by Time

// Pass `IncludeRevisions` a `DateTime` value
var query = session.Query<User>()
    .Include(builder => builder
        .IncludeRevisions(creationTime.ToUniversalTime()));

// The revision has been included by its creation time,
// and is now retrieved locally from the session
var revision = session
    .Advanced.Revisions.Get<User>(id, creationTime.ToUniversalTime());

Query: Include Revisions by Change Vector

// Include the revision whose change vector is stored in
// "ContractRev_2_ChangeVector",
// and the revisions whose change vectors are stored in
// "ContractRevChangeVectors"
var query = session.Load<Contract>(id, builder => builder
    .IncludeRevisions(creationTime)
    .IncludeRevisions(x => x.ContractRev_2_ChangeVector)
    .IncludeRevisions(x => x.ContractRevChangeVectors));

// The revisions have been included by change vectors,
// and are now retrieved locally from the session
var revision = query.ContractRev_2_ChangeVector;
var revisions = query.ContractRevChangeVectors;

Including Revisions with Session.Advanced.RawQuery

  • To include revisions by time or change vector, pass the raw query include revisions command either a DateTime value or a path to a change vector document property.
  • RavenDB will figure out by itself whether the parameter you passed was a DateTime values or a path, and include revisions accordingly.
  • Aliases (e.g. from Users as U) are not supported by raw queries that include revisions.

Raw Query: Include Revisions by Time

// Pass the `include revision` command a `DateTime` value
var query = session.Advanced
    .RawQuery<User>("from Users include revisions($p0)")
    .AddParameter("p0", creationTime.ToUniversalTime())
    .ToList();

// The revision has been included by its creation time,
// and is now retrieved locally from the session
var revision = session
    .Advanced.Revisions.Get<User>(id, creationTime.ToUniversalTime());

Raw Query: Include Revisions by Change Vector

// Pass the `include revision` command a `path`
// to a document property that holds change vector/s,
var query = session.Advanced
    .RawQuery<Contract>("from Users where Name = 'JohnDoe' include revisions($p0)")
    .AddParameter("p0", "ContractRev_1_ChangeVector")
    .ToList();

// The revision has been included by change vector,
// and is now retrieved locally from the session
var revision = session.Advanced.Revisions.Get<Contract>(changeVector);