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