Raven Db with F# (FSharpEnt.RavenDB)

 

Update: This is now the F# raven client, distributed as part of the raven db tool chain

Raven DB is a Document database from Ayende (Hibernating Rhinos). The API is nice and clean and a dream to use to C#. However, although the api is functional (i.e. modelled on linq) it is not very nice to use from F#. This is mainly due to the heavy use of Linq.Expressions, and the lack of support for implicit conversion between functions and expressions. (I guess this may change in F# 3.0 as linq queries become more embedded into the language in the form of query expressions)

Getting Started
The wrapper is available on nuget. To install simply enter the following command into the Nuget package manager console.

Install-Package FSharpEnt.RavenDB

This should then download the dependencies and off you go, the library only has a dependency on the RavenDB.Client library, so it does not get the Embedded or Standalone servers that Raven offers, if you don’t have a Document store instance already running you can follow the instructions here to get started with Raven.

Once you have a server up and running, time to set up the application.

Usage

The application can be initialised via passing in a preconfigured document store or using a connection string from the web config

//Embedded Document store
let docStore = (new EmbeddableDocumentStore(RunInMemory = true)).Initialize()
Raven.initWithDocumentStore "myStore" docStore

//From connections string
Raven.initWithConnectionString "myStore" "myConnectionStringFromAppConfig"

once the store has been initialised we can begin to use raven to execute queries and store data. Using this we can initialise many stores pointing to various different databases if needed, and pick out the desired store at run time.

To store data into a the ‘myStore’ instance of raven

let customer = Customer.Create("Test", (new DateTime(2012, 1, 1)))
let stored = withSession "myStore" (store customer)

or using the workflow expression syntax

//Once only initialisation
let raven = RavenBuilder("myStore")
raven {
       let! stored = storeMany (createCustomers 365)
       return stored
}

To query via combinators

let actual : seq<Customer> =
          query (where <@ fun x -> x.Dob < new DateTime(2012,2,1) @>)
          |> withSession "myStore"

or monadic

raven {
        let! actual = queryAllBy (where <@ fun x -> x.Dob < new DateTime(2012,8,1) @>)
        return actual
}

other more advanced scenarios are supported, for example server side joins,

raven {
      do! store customer >> ignore
      do! store order >> ignore
      return! (fun s ->
                     let order = ``include`` <@ fun s -> s.Customer @> (fun s -> s.Load("orders/1")) s
                     let customer : Customer = s.Load(order.Customer)
                     order, customer)
}

the code for this is hosted at Bitbucket feel free to check it out and contribute your own additions.

Advertisements
This entry was posted in Development and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s