The blog of the F# team at Microsoft
[ Update: the Freebase type provider is now available as part of the FSharp.Data NuGet package. The namespace has changed from "Samples.DataStore.Freebase" to "FSharp.Data" ]
Part 1 - The Freebase Type Provider Sample - Integrating Internet-Scale Data Sources into a Strongly Typed LanguagePart 2 - The Freebase Type Provider Sample - Static ParametersPart 3 - The Freebase Type Provider Sample - Sample Queries for Presidents, Books and StarsPart 4 - The Freebase Type Provider Sample - Some Info On Queries
The F# 3.0 Freebase Type Provider Sample includes some support for query translation from F# 3.0 LINQ queries to MQL. Some sample queries are here. You can write queries in F# 3.0 with auto-completion and strong typing, and still execute efficiently on the server, at least for those queries translated by the sample. Here are some details query translation in the sample at the time of writing.
Single, non-nested 'for' loops over a collection,
for book in data.``Arts and Entertainment``.Books.Books do
Where clauses with a fairly simple range of constraints, e.g.
where (e.``Atomic number``.Value = 20) // equality on primitive values
where (isotope.``Isotope of``.``Atomic number``.Value = 20) // equality on nested value
where (e.``Atomic number``.Value < 20) // ordering relations on primitive values
where e.``Atomic number``.HasValue // non-emptiness of primitive values
where (x.Damages <> null) // non-emptiness of compound collections
where (elem.Symbol = "Na") // string equality
Approximate string matching, see the MQL cookbook operator "~="
where (book.Name.ApproximatelyMatches "1984")
Selecting things at the end of a query (if the items may contain unrealized compund objects, then those items will be populated on-demand)
select (e.Name, e.``Boiling Point``)
Sorting on properties
sortBy e.Name
sortBy e.``Boiling Point``.Value
sortByNullable e.``Boiling Point``
Exact counting, and Freebase approximate counting
query { ... count }, or
// Exact count of number of countries, some are historical data.``Time and Space``.Location.Countries.Count()
// Approximate count of number of books. There are around three million books // to search. Counting them exactly takes too long on the server data.``Arts and Entertainment``.Books.Books.ApproximateCount()
At the time of writing there are some limitations
By default, the portion of queries that can't be executed on the server gets executed on the client side. You can adjust that behaviour to throw an exception instead by setting AllowLocalQueryEvaluation to false. Executing on the client side can give a much nicer programming experience for data scripting against small data sets (or prefixes of large data sets), but obviously for much larger data sets such as "books" or "films" this is not appropriate.In data scripting a bit of local query evaluation may not matter (you can always interrupt execution), but in finished applications you will want to avoid it.
Note, it is helpful to add the following to see how many requests are being sent to the server:
data.DataContext.SendingRequest.Add (fun e -> printfn "request: %A" e.RequestUri)