You are currently browsing legacy 1.0 version of documentation. Click here to switch to the newest 5.0 version.

We can help you with migration to the latest RavenDB

Contact Us Now
see on GitHub

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 |> run session

alternatively using the computation expression syntax

raven {
    return! store customer
} |> 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 <@ fun x -> x.Dob < new DateTime(2012,1,7) @>)
    }

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 -> 
                          let order = including <@ fun s -> s.Customer @> (fun s -> 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 <@ fun x -> x.Dob = date @>)
    }

let customersWithDob (date : DateTime) = 
    raven { 
        return! query (where <@ fun x -> x.Dob < date @>)
    }

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