Last active
June 1, 2022 08:15
-
-
Save mjul/f5c936d116a2b89c3da8f63afad628e7 to your computer and use it in GitHub Desktop.
Elasticsearch in F# example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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