Skip to content

Instantly share code, notes, and snippets.

@mjul
Last active June 1, 2022 08:15
Show Gist options
  • Save mjul/f5c936d116a2b89c3da8f63afad628e7 to your computer and use it in GitHub Desktop.
Save mjul/f5c936d116a2b89c3da8f63afad628e7 to your computer and use it in GitHub Desktop.
Elasticsearch in F# example
// paket add nuget NEST
#I "../../packages"
#r "Elasticsearch.Net/lib/net46/Elasticsearch.Net.dll"
#r "NEST/lib/net46/Nest.dll"
open System
//open Elasticsearch.Net
open Nest
let node = new Uri("http://127.0.0.1:9200")
let settings = new ConnectionSettings(node)
let client = new ElasticClient(settings)
type Tweet = {Id: int; User: string; PostDate: DateTime; Message: string}
let tweet = {Id = 1; User = "kimchy"; PostDate = new DateTime(2009, 11, 15); Message = "Trying out NEST, so far so good?"}
let indexName (name:string) =
IndexName.op_Implicit name
let myTweetIndex = indexName "mytweetindex"
let indexer index (ides:IndexDescriptor<'T>) =
ides.Index(index) :> IIndexRequest
// Convert F# functions to System.Func<_,_> types
// for interop with the Elasticsearch NEST API
let func (f:('a->'b)) =
new Func<'a,'b>(f)
let indexResult = client.Index<Tweet>(tweet, func (indexer myTweetIndex))
printfn "** Indexed: Id=%s" indexResult.Id
let documentPath idx docType (id:string) =
(DocumentPath<Tweet>.op_Implicit id).Index(idx).Type(docType)
let getResult = client.Get(documentPath myTweetIndex (TypeName.From<Tweet>()) indexResult.Id)
printfn "** GET RESULT:%s%A" Environment.NewLine getResult.Source
let searchAllResult = client.Search<Tweet>()
printfn "** SEARCH ALL RESULT:%s%A" Environment.NewLine searchAllResult.Documents
open Microsoft.FSharp.Linq.RuntimeHelpers
open System
open System.Linq.Expressions
// F# func to Linq expression converter function from: http://fssnip.net/ts
module Lambda =
let toExpression (``f# lambda`` : Quotations.Expr<'a>) =
``f# lambda``
|> LeafExpressionConverter.QuotationToExpression
|> unbox<Expression<'a>>
// search the Message text
let bodyField = Field.op_Implicit (Lambda.toExpression <@ new Func<Tweet,string>(fun (o:Tweet) -> o.Message) @>)
let querySelector query (sd:SearchDescriptor<Tweet>) =
sd.From(0).
Size(50).
Query(func (fun q ->
q.QueryString(func (fun qs ->
qs.DefaultField(bodyField).Query(query) :> IQueryStringQuery))))
:> ISearchRequest
let searchReq = func (querySelector "NEST")
let searchResult = client.Search<Tweet>(searchReq)
printfn "** SEARCH RESULT:%s%A" Environment.NewLine searchResult.Documents
//
// Index some source files
//
type SourceFile = {Timestamp: DateTime; Path: string; Name: string; Contents: string}
open System.IO
let sourceFiles = Directory.GetFiles(@"C:\src\mycode", "*.fs", System.IO.SearchOption.AllDirectories)
let mySourceIndex = indexName "sourcecode"
for fname in sourceFiles do
let sf = {Timestamp=File.GetCreationTimeUtc(fname); Name=Path.GetFileName(fname); Path=Path.GetDirectoryName(fname) ; Contents=File.ReadAllText(fname) }
printfn "Indexing %s..." fname
client.Index<SourceFile>(sf, func (indexer mySourceIndex)) |> ignore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment