I spend a few hours learning how to use RavenDB yesterday. I first read through the tutorials and documentation on the home page for RavenDB. Unfortunately, the docs are way out of date, as the codebase for RavenDB appears to be moving and changing rapidly.
The first hurdle was that the documentation doesn't explain what namespaces are needed to use for what functionality. This seems to be a frequent problem an 3rd party APIs. I'm specifically testing the embedded stuff. I used the latest build, which is RavenDB-Build-206.
Here's how you setup saving:
using Raven.Client.Client;
public void Save()
{
var store = new EmbeddableDocumentStore { DataDirectory = DALUtils.GetDbPath() };
store.Initialize();
var session = store.OpenSession();
session.Store(this);
session.SaveChanges();
session.Dispose();
}
My take-away from this code is that saving to the datastore is EXTREMELY easy. So the steps for saving are:
- Create an EmbeddableDocumentStore.
- Give it the path you want it to create the document files in.
- Initialize the data store.
- Create a session.
- Use the session to actually store. Note that this does not actually save the current document.
- Save the changes.
- This is optional, but always a good idea, dispose of the session.
Now the hard part, at least to me, is retrieving this back. I have been able to look at the actual document that got stored. I used that knowledge to write a simple function that loads thae class document from disk. The raw JSON for this document looks like this:
{
"Name":"CrashTestDummy",
"Password":"dummy",
"Gender":"Male",
"TimeInstantiated":"12/5/2010 10:27:44 PM"
}
The properties were declared like this:
public enum GenderTypes
{
Male,
Female,
Neuter
}
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name for this player.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the password.
/// </summary>
/// <value>The password.</value>
public string Password { get; set; }
/// <summary>
/// Gets or sets the gender.
/// </summary>
/// <value>The gender.</value>
public GenderTypes Gender { get; set; }
/// <summary>
/// Gets or sets the time instantiated.
/// </summary>
/// <value>The time instantiated.</value>
public string TimeInstantiated { get; set; }
The metadata is this:
{
"Content-Encoding":"gzip",
"Raven-Entity-Name":"PlayerBehaviors",
"Raven-Clr-Type":"Behaviors.PlayerBehavior, Behaviors"
}
Loading this dynamically like I do from databases has eluded me. You normally would use a LINQ query to get the object. These three queries work:
from doc in docs
where doc.Name == "CrashTestDummy"
select new { doc.Name }
from doc in docs
where doc.Name == "CrashTestDummy"
select doc
from doc in docs
where doc["@metadata"]["Raven-Entity-Name"] == "PlayerBehaviors"
select doc
What is baffling me specifically, is how to create an index that I can query against. I got the queries above, after I read an entry in the ravendb Google Groups.
The previous version of the save code, just saved the properties stored in a dictionary. So the old document looks like this:
{
"Id":"57b7b3a0-ad7b-46e1-bb92-d0bb879d6522",
"Name":"CrashTestDummy",
"Password":"dummy",
"Gender":"Male"
}
The metadata is this:
{
"Content-Encoding":"gzip",
"Raven-Entity-Name":"DictionariesOfStringsOfStrings",
"Raven-Clr-Type":"System.Collections.Generic.Dictionary`2[]System.String, mscorlib[]System.String, mscorlib[], mscorlib"
}
So to load this I did this:
public Dictionary<string, string> Load(string playerName)
{
var session = _store.OpenSession();
var playerProperties = session.Load<Dictionary<string, string>>("dictionariesofstringsofstrings/1");
session.Dispose();
return playerProperties;
}
I haven't changed this to work with the new save method, which uses the actual PlayerBehavior class for saving.
So this is as far as I've gotten by myself. I'm going to need to post some questions on the ravendb Google Groups, to move me forward from my current rut.
The management UI is not out yet, but I did find a workaround. RavenDB comes with a built-in server. I copied the data folder into the Data folder that sits on the same directory as Raven.Server.exe. This is a minuature web server. Once you start this server, you point your browser to http://localhost:8080 to see the web UI. That was good enough to let me examine the documents.
Anyways, I'm pretty tired, so I'm going to stop here.