Date post: | 05-Dec-2014 |
Category: |
Technology |
Upload: | mongodb |
View: | 2,050 times |
Download: | 2 times |
MongoDB F# DriverMax Hirschhorn (@visemet)github.com/10gen-interns/mongo-fsharp-driver-prototype
Outline1. Brief overview of MongoDB
2. Introduction to F# language
3. Structure of F# + .NET drivers
4. Installing the driver
5. Connecting to the server
6. Executing operations
MongoDB Overview● Popular NoSQL database
● Stores BSON, binary-form of JSON
● Interact with (query, etc.) using JSON
What is F#?● Multi-paradigm (functional, OO, imperative)
● Statically-typed + type inference system
● Compatible with other .NET languages
● Syntax similar to Ocaml
Functions and typesSame primitives as with .NET
Able to curry parameters and partially apply functions
// int -> int -> intlet add x y = x + y
// int -> intlet inc = add 1// int -> int
let double x = add x x
// Definition// 'a -> ('a -> 'b) -> 'blet (|>) x f = f x
// Usage100 |> inc |> double// ~~> 202
|> (forward pipe) operator
Refactored into a separate Core.dll to provide low-level operations
Structure of .NET driver
Core BSON
F# high- level
C# high- level
InstallationNot available on NuGet (yet)
1. Clone from GitHub2. Build solution3. Add references to project
ConnectingMaintains naming convention
let client = // localhost:27017MongoClient() :> IMongoClient
let db = client.GetDatabase "test"
let items = db.GetCollection "items"
- or -
let items = db.GetCollection<'DocType> "items"
Insertslet doc =BsonDocument("foo", BsonInt32(1))
items.Insert doc
Supports (automatic) serialization of● record types● discriminated unions● option types
DeletesChain together operations with predicate
let query = ...items.Find(query)|> Scope.remove
Queries before (1)C#new BsonDocument {
{ "price", 1.99 },{ "$or", new BsonDocument {
{ "qty", new BsonDocument { { "$lt", 20 } } },{ "sale", true }
} }};
F#BsonDocument([ BsonElement("price", BsonDouble(1.99)) BsonElement("$or", BsonArray([ ... ])) ])
Queries before (2)Query builderQuery.And([ Query.EQ("price", BsonDouble(1.99)) Query.OR([ Query.LT("qty", BsonInt32(20)) Query.EQ("sale", BsonBoolean(true)) ]) ])
Typed query builderlet query = QueryBuilder<Item>()
query.And([ query.EQ((fun x -> x.price), 1.99) query.OR([ query.LT((fun x -> x.qty), 20) query.EQ((fun x -> x.sale), true) ]) ])
Collection SchemaUse cases for query/update operations against a collection1. Unknown schema
2. Given schema, typed defined by developer
3. Inferred schema, where operations are checked at compile-time
? (dynamic get) operator
Performs dictionary lookup
doc?foo // ~~> doc.["foo"] okdoc?bar // ~~> doc.["bar"] fails
Queries after
Now able to be written using● code quotations● computation expressions
Reuse built-in operators wherever possible
Type-checked
<@ fun (x : Item) ->
x.price = 1.99 && (x.qty < 20 || x.sale = true) @>
|> bson
and -unchecked versions
<@ fun (x : BsonDocument) ->
x?price = 1.99 && (x?qty < 20 || x?sale = true) @>
|> bson
bson quotations
mongo expressionsCollection can be typed or untyped
mongo {for x in items dowhere (x.price = 1.99
&& (x.qty < 20 || x.sale = true))
}
?<- (dynamic set) operator (2)
Performs dictionary assignment
doc?foo <- 0// ~~> doc.["foo"] = 0 ok
doc?bar <- 0// ~~> doc.["bar"] = 0 fails
UpdatesAgain able to be written using
● code quotations● computation expressions
Reuse built-in operators wherever possible
bson quotations (1)Type-checked versionImmutable fields<@ fun (x : Item) ->
{ x with price = 0.99; qty = x.qty + 10 } @>
|> bson
Mutable fields<@ fun (x : Item) ->
[ x.price <- 0.99; x.qty <- x.qty + 10 ] @>
|> bson
bson quotations (2)Type-unchecked versionSugared<@ fun (x : BsonDocument) ->
[ x?price <- 0.99; x?qty <- (+) 10 ] @>
|> bson
Unsugared<@ fun (x : BsonDocument) ->
[ x?price <- 0.99; x?qty <- x?qty + 10 ] @>
|> bson
mongo expressionsCollection can be typed or untyped
mongo {for x in items doupdateset x.price 0.99inc x.qty 10
}
Questions?
Special thanks to…Sridhar NanjundeswaranCraig WilsonRobert StamMathias BrandewinderDon SymeKeith BattocchiTomas Petricek
… and the F# community on Twitter
Record Serialization (1)Set of named values
// Example definitiontype Item = {price : floatqty : intsale : bool
}
Record Serialization (2)// Example usagelet item = { price = 1.99 qty = 20 sale = true }
// ~~> serialized as JSON// { price: 1.99// , qty: 20// , sale: true }
Union Serialization (1)Discriminated union is a series of casesof (potentially) varying arity and types
type Number = | Zero | One of int | Two of int * string
Union Serialization (2)let zero = Zerolet one = One 1let two = Two (2, "two")
// ~~> serialized as JSON// { _t: "Zero" }// { _t: "One", Item: 1 }// { _t: "Two"// , Item1: 2// , Item2: "two" }
Option SerializationHaskell-inspired equivalent of Just/Nothing
Serialize the enclosed value when Some case, and omit when None case
Used to represent heterogeneous documents within collection