Skip to main content

The F# Client API

The F# client API is a thin wrapper around the standard RavenDB client API, that provides a small set of combinators and a computation builder that hides the complexity of dealing with Linq expressions from F#.

This documentation assumes some familiarity with the basics of RavenDB.

Creating a Document Store

the F# language, contains a type called Discriminated Unions / Algebraic Data Types. By default the JSON.net serializer that RavenDB uses cannot (de)serialize these types.

The Raven DB F# client library comes with a JSON.net converter that allows these types to be handled. But we need to customize the document store. This can be achieved by adding the following code.

store.Conventions.CustomizeJsonSerializer <- (fun s -> s.Converters.Add(new UnionTypeConverter()))

alternatively the library provides an extension method on DocumentStore that creates a document store based on a named Connection String.

DocumentStore.OpenInitializedStore("RavenDb")

Data Model

Throughout the examples we will use the following Data Model


type Product = {
mutable Id : string
Name : string
Price : float
}

type Order = {
mutable Id : string
Date : DateTimeOffset
Customer : string
Items : Product array
}

type CustomerAttachementMetaData = {
Description : string
}

type Customer = {
mutable Id : string
Name : string
Dob : DateTime
}

Inserting Data

To insert data we can simply run the following expression,


let customer =
{ Id = null; Name = "Test"; Dob = DateTimeOffset.Now.Date}

use session = docStore.OpenSession()
store customer |&gt; run session

alternatively using the computation expression syntax


raven {
return! store customer
} |&gt; run session

Queries

To query for all of the customers in our database born before 7/1/2012 we can write something like the following...


let customerQuery =
raven {
return! query (where &lt;@ fun x -&gt; x.Dob &lt; new DateTime(2012,1,7) @&gt;)
}

This defines the query, but at this point the query has not been executed, To execute the query we can then execute

let result = use session = docStore.OpenSession() customerQuery |> run session

Includes (joins)

One of the neat features of raven is that it support joins on the server side, so I can get a document and other related documents back in a single call across the wire,

From the data model above we can see that a order has a reference to a customer, to retrieve this in a single call we can create the following query


let orderIncludingCustomer =
raven {
return! (fun s -&gt;
let order = including &lt;@ fun s -&gt; s.Customer @&gt; (fun s -&gt; s.Load("orders/1")) s
let customer : Customer = s.Load(order.Customer)
order, customer
)
}

and then run it

use session = docStore.OpenSession() orderIncludingCustomer |> run session

as you can see this query will return you a tuple of order & customer.

Composition of queries

Due to the functional nature of the API we have the ability to compose queries.

For example let's say we wanted all of the customers born on a certain date and all of the orders placed on that same date. We can define the following


let ordersOn (date : DateTime) =
raven {
return! query (where &lt;@ fun x -&gt; x.Dob = date @&gt;)
}

let customersWithDob (date : DateTime) =
raven {
return! query (where &lt;@ fun x -&gt; x.Dob &lt; date @&gt;)
}

let composedQuery date =
raven {
let! orders = ordersOn date
let! customers = customersWithDob date
return orders, customers
}

We can then execute this query as normal

use session = docStore.OpenSession() composedQuery (new DateTime(2012, 1, 1)) |> run session