diff --git a/Elasticsearch.FSharp.sln b/Elasticsearch.FSharp.sln index 2d0349b..56d6ea4 100644 --- a/Elasticsearch.FSharp.sln +++ b/Elasticsearch.FSharp.sln @@ -3,15 +3,16 @@ Microsoft Visual Studio Solution File, Format Version 12.00 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC92765B-25F4-41AB-A282-282B5399ACCA}" ProjectSection(SolutionItems) = preProject .gitignore = .gitignore + README.md = README.md EndProjectSection EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Elasticsearch.FSharp", "src\Elasticsearch.FSharp\Elasticsearch.FSharp.fsproj", "{69E3270B-8AC7-433A-83F7-D6C3505C5C87}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{09ABBCAA-2DA8-4F73-A61F-EEBFC6A4C8E7}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{C7CA7432-0FBF-42DC-9D65-41A5AD510829}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Elasticsearch.FSharp.Tests", "tests\Elasticsearch.FSharp.Tests\Elasticsearch.FSharp.Tests.fsproj", "{0BA09266-FC24-40E8-B60C-E072EF0E08B4}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Elasticsearch.FSharp", "src\Elasticsearch.FSharp\Elasticsearch.FSharp.fsproj", "{3C96FF6B-EA2C-4678-A5F6-E0880267542A}" +EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Elasticsearch.FSharp.Tests", "tests\Elasticsearch.FSharp.Tests\Elasticsearch.FSharp.Tests.fsproj", "{1AD77E98-F150-41F0-9347-766A00C85A8A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -19,17 +20,17 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {69E3270B-8AC7-433A-83F7-D6C3505C5C87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {69E3270B-8AC7-433A-83F7-D6C3505C5C87}.Debug|Any CPU.Build.0 = Debug|Any CPU - {69E3270B-8AC7-433A-83F7-D6C3505C5C87}.Release|Any CPU.ActiveCfg = Release|Any CPU - {69E3270B-8AC7-433A-83F7-D6C3505C5C87}.Release|Any CPU.Build.0 = Release|Any CPU - {0BA09266-FC24-40E8-B60C-E072EF0E08B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0BA09266-FC24-40E8-B60C-E072EF0E08B4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0BA09266-FC24-40E8-B60C-E072EF0E08B4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0BA09266-FC24-40E8-B60C-E072EF0E08B4}.Release|Any CPU.Build.0 = Release|Any CPU + {3C96FF6B-EA2C-4678-A5F6-E0880267542A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3C96FF6B-EA2C-4678-A5F6-E0880267542A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3C96FF6B-EA2C-4678-A5F6-E0880267542A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3C96FF6B-EA2C-4678-A5F6-E0880267542A}.Release|Any CPU.Build.0 = Release|Any CPU + {1AD77E98-F150-41F0-9347-766A00C85A8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1AD77E98-F150-41F0-9347-766A00C85A8A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1AD77E98-F150-41F0-9347-766A00C85A8A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1AD77E98-F150-41F0-9347-766A00C85A8A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution - {69E3270B-8AC7-433A-83F7-D6C3505C5C87} = {09ABBCAA-2DA8-4F73-A61F-EEBFC6A4C8E7} - {0BA09266-FC24-40E8-B60C-E072EF0E08B4} = {C7CA7432-0FBF-42DC-9D65-41A5AD510829} + {3C96FF6B-EA2C-4678-A5F6-E0880267542A} = {09ABBCAA-2DA8-4F73-A61F-EEBFC6A4C8E7} + {1AD77E98-F150-41F0-9347-766A00C85A8A} = {C7CA7432-0FBF-42DC-9D65-41A5AD510829} EndGlobalSection EndGlobal diff --git a/packages.config b/packages.config deleted file mode 100644 index 8c0f973..0000000 --- a/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/Builders/Aggs/AggBuilder.fs b/src/Elasticsearch.FSharp/Builders/Aggs/AggBuilder.fs new file mode 100644 index 0000000..3128ec2 --- /dev/null +++ b/src/Elasticsearch.FSharp/Builders/Aggs/AggBuilder.fs @@ -0,0 +1,18 @@ +namespace Elasticsearch.FSharp.Builders.Aggs + +type AggBuilder(name: string) = + + [] + member x.Body(a, t) = + a + + [] + member x.Aggs(a, b) = + a + + [] + member x.Meta(a, b) = + a + + member x.Yield(a) = + a \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/Builders/Aggs/TermsBuilder.fs b/src/Elasticsearch.FSharp/Builders/Aggs/TermsBuilder.fs new file mode 100644 index 0000000..a4223ea --- /dev/null +++ b/src/Elasticsearch.FSharp/Builders/Aggs/TermsBuilder.fs @@ -0,0 +1,19 @@ +namespace Elasticsearch.FSharp.Builders.Aggs + +type TermsBuilder() = + + [] + member x.Field(a, f) = + a + + [] + member x.Size(a, s) = + a + + [] + member x.ShowTermDocCountError(a, b:bool) = + a + + member x.Yield(a) = + a + diff --git a/src/Elasticsearch.FSharp/Builders/ElasticBuilder.fs b/src/Elasticsearch.FSharp/Builders/ElasticBuilder.fs new file mode 100644 index 0000000..a940ac8 --- /dev/null +++ b/src/Elasticsearch.FSharp/Builders/ElasticBuilder.fs @@ -0,0 +1,28 @@ +namespace Elasticsearch.FSharp.Builders + +open System +open Nest + +type ElasticBuilder<'T when 'T: not struct>() = + + let search = SearchDescriptor<'T>() + + [] + member x.Size(a, size: int) = + search.Size(Nullable size) + + [] + member x.Query(a, q: Func, QueryContainer>) = + search.Query(q) + + [] + member x.Aggs(a, aggs) = + () + + [] + member x.Sort(a, sort) = + () + + member x.Yield(a) = + search + \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/Builders/Query/BoolBuilder.fs b/src/Elasticsearch.FSharp/Builders/Query/BoolBuilder.fs new file mode 100644 index 0000000..b224616 --- /dev/null +++ b/src/Elasticsearch.FSharp/Builders/Query/BoolBuilder.fs @@ -0,0 +1,37 @@ +namespace Elasticsearch.FSharp.Builders.Query + +open System +open Nest + +type BoolBuilder<'T when 'T: not struct>() = + + let calls = ResizeArray() + + [] + member x.Must(a, b: Func, QueryContainer> seq) = + calls.Add(fun (x:BoolQueryDescriptor<'T>) -> x.Must b) + a + + [] + member x.MustNot(a, b: Func, QueryContainer> seq) = + calls.Add(fun (x:BoolQueryDescriptor<'T>) -> x.MustNot b) + a + + [] + member x.Should(a, b: Func, QueryContainer> seq) = + calls.Add(fun x -> x.Should b) + a + + [] + member x.MinimumShouldMatch(a, v: string) = + calls.Add(fun x -> x.MinimumShouldMatch(MinimumShouldMatch.op_Implicit v)) + a + + member x.Yield(_) = + Func<_,_>( + fun (q: QueryContainerDescriptor<'T>) -> + q.Bool( + fun boolQueryDescriptor -> + Seq.fold (fun x f -> f x) boolQueryDescriptor calls :> IBoolQuery + ) + ) diff --git a/src/Elasticsearch.FSharp/Builders/Query/MatchAllBuilder.fs b/src/Elasticsearch.FSharp/Builders/Query/MatchAllBuilder.fs new file mode 100644 index 0000000..676b739 --- /dev/null +++ b/src/Elasticsearch.FSharp/Builders/Query/MatchAllBuilder.fs @@ -0,0 +1,12 @@ +namespace Elasticsearch.FSharp.Builders.Query + +open System +open Nest + +type MatchAllBuilder() = + + member x.Zero() = + Func<_,_>( + fun (q: QueryContainerDescriptor<'T>) -> + q.MatchAll() + ) \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/Builders/Sort/SortByBuilder.fs b/src/Elasticsearch.FSharp/Builders/Sort/SortByBuilder.fs new file mode 100644 index 0000000..93c6596 --- /dev/null +++ b/src/Elasticsearch.FSharp/Builders/Sort/SortByBuilder.fs @@ -0,0 +1,17 @@ +namespace Elasticsearch.FSharp.Builders.Sort + +type SortByBuilder() = + + [] + member x.Field(a, b) = + a + + [] + member x.Order(a, b) = + a + + [] + member x.Mode(a, b) = + a + + member x.Yield(a) = a diff --git a/src/Elasticsearch.FSharp/DSL/Aggs.fs b/src/Elasticsearch.FSharp/DSL/Aggs.fs deleted file mode 100644 index a59550c..0000000 --- a/src/Elasticsearch.FSharp/DSL/Aggs.fs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type AggsFieldsBody = - | NamedAgg of string * AggBody - | MoreAggs of AggsFieldsBody list - | FilterAgg of string * QueryBody * AggBody - -and AggWeightConfig = - | WeightField of string - | Weight of string - -and AggParam = - | AggScript of (ScriptField list) - | AggValue of string - | AggField of string - | AggWeight of AggWeightConfig - | AggInterval of string - | AggFormat of string - | AggSize of int - -and AggBody = - | Avg of AggParam list - | WeightedAvg of AggParam list - | Max of AggParam list - | Min of AggParam list - | Sum of AggParam list - | Stats of AggParam list - | AggTerms of AggParam list - | AggDateHistogram of AggParam list diff --git a/src/Elasticsearch.FSharp/DSL/Queries/MatchPhrasePrefixQuery.fs b/src/Elasticsearch.FSharp/DSL/Queries/MatchPhrasePrefixQuery.fs deleted file mode 100644 index 2a156f0..0000000 --- a/src/Elasticsearch.FSharp/DSL/Queries/MatchPhrasePrefixQuery.fs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type MatchPhrasePrefixQuery = string * (MatchPhrasePrefixQueryField list) - -and MatchPhrasePrefixQueryField = - | MatchQuery of string - | MaxExpansions of int32 \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Queries/MatchQuery.fs b/src/Elasticsearch.FSharp/DSL/Queries/MatchQuery.fs deleted file mode 100644 index 785a5c6..0000000 --- a/src/Elasticsearch.FSharp/DSL/Queries/MatchQuery.fs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type MatchQuery = string * (MatchQueryField list) - -and MatchQueryField = - | Operator of string - | ZeroTermsQuery of string - | MatchQuery of string - | CutoffFrequency of double \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Queries/MultiMatchQuery.fs b/src/Elasticsearch.FSharp/DSL/Queries/MultiMatchQuery.fs deleted file mode 100644 index 9e0c31b..0000000 --- a/src/Elasticsearch.FSharp/DSL/Queries/MultiMatchQuery.fs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type MultiMatchQuery = MultiMatchQueryField list - -and MultiMatchQueryField = - | Fields of string list - | MultiMatchQuery of string - | QueryType of string - | MaxExpansions of int - | Slop of int - | TieBreaker of float - | MultiMatchRaw of key:string * value:string - diff --git a/src/Elasticsearch.FSharp/DSL/Queries/RangeQuery.fs b/src/Elasticsearch.FSharp/DSL/Queries/RangeQuery.fs deleted file mode 100644 index 1cae2ad..0000000 --- a/src/Elasticsearch.FSharp/DSL/Queries/RangeQuery.fs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type RangeQuery = string * (RangeQueryField list) - -and RangeQueryField = - | Gte of string - | Gt of string - | Lte of string - | Lt of string - | RangeTimeZone of string \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Queries/ScriptQuery.fs b/src/Elasticsearch.FSharp/DSL/Queries/ScriptQuery.fs deleted file mode 100644 index 5f13efc..0000000 --- a/src/Elasticsearch.FSharp/DSL/Queries/ScriptQuery.fs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type ScriptQuery = ScriptField list - \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Queries/TermQuery.fs b/src/Elasticsearch.FSharp/DSL/Queries/TermQuery.fs deleted file mode 100644 index f857f65..0000000 --- a/src/Elasticsearch.FSharp/DSL/Queries/TermQuery.fs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type TermQuery = string * (TermQueryField list) - -and TermQueryField = - | ExactValue of string - diff --git a/src/Elasticsearch.FSharp/DSL/Queries/TermsQuery.fs b/src/Elasticsearch.FSharp/DSL/Queries/TermsQuery.fs deleted file mode 100644 index 80c65ac..0000000 --- a/src/Elasticsearch.FSharp/DSL/Queries/TermsQuery.fs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type TermsQuery = string * (TermsQueryField list) - -and TermsQueryField = - | ValueList of string list - | FromIndex of string * string * string * string \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Query.fs b/src/Elasticsearch.FSharp/DSL/Query.fs deleted file mode 100644 index 92aa425..0000000 --- a/src/Elasticsearch.FSharp/DSL/Query.fs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type QueryBody = - | MatchAll - | MatchNone - | IDs of string list - | Bool of BoolQuery list - | Match of MatchQuery - | Term of TermQuery - | Terms of TermsQuery - | Range of RangeQuery - | Script of ScriptQuery - | MultiMatch of MultiMatchQuery - | MatchPhrasePrefix of MatchPhrasePrefixQuery - | Exists of fieldName:string - | Raw of rawString:string - | TypeEquals of string - -and BoolQuery = - | Must of QueryBody list - | Filter of QueryBody list - | Should of QueryBody list - | MustNot of QueryBody list - | MinimumShouldMatch of string \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Script.fs b/src/Elasticsearch.FSharp/DSL/Script.fs deleted file mode 100644 index 96e0688..0000000 --- a/src/Elasticsearch.FSharp/DSL/Script.fs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type ScriptFieldsBody = string * (ScriptField list) - -and ScriptField = - | Source of string - | Lang of string - | Params of (string * string) list - | ScriptId of string \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Search.fs b/src/Elasticsearch.FSharp/DSL/Search.fs deleted file mode 100644 index cdbb0be..0000000 --- a/src/Elasticsearch.FSharp/DSL/Search.fs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type ElasticDSL = - | Search of SearchBody list - -and SearchBody = - | Query of QueryBody - | Sort of SortBody list - | ScriptFields of ScriptFieldsBody list - | Aggs of AggsFieldsBody list - | From of int - | Size of int - | Source_ of SourceBody - | Raw of key:string * value:string \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Aggs.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Aggs.fs deleted file mode 100644 index 03a53dd..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Aggs.fs +++ /dev/null @@ -1,51 +0,0 @@ -module internal Elasticsearch.FSharp.DSL.Serialization.Aggs - -open Elasticsearch.FSharp.DSL -open Elasticsearch.FSharp.DSL.Serialization - -let AggParamsToJSON (aggParams:AggParam list) = - [ - for param in aggParams -> - match param with - | AggScript scriptBody -> "\"script\":{" + (Script.ScriptFieldsToJSON scriptBody) + "}" - | AggValue value -> "\"value\":\"" + value + "\"" - | AggField field -> "\"field\":\"" + field + "\"" - | AggWeight weightConfig -> - match weightConfig with - | WeightField field -> "\"weight\":{\"field\":\"" + field + "\"}" - | Weight weight-> "\"weight\":\"" + weight + "\"" - | AggInterval interval -> "\"interval\":\"" + interval + "\"" - | AggFormat format -> "\"format\":\"" + format + "\"" - | AggSize size -> "\"size\":" + size.ToString() - ] |> String.concat "," - -let AggBodyToJSON ((name, body): (string * AggBody)) = - "\"" + name + "\":{" + - ( - let aggName, aggBody = - match body with - | Avg aggParams -> "avg", AggParamsToJSON aggParams - | WeightedAvg aggParams -> "weighted_avg", AggParamsToJSON aggParams - | Max aggParams -> "max", AggParamsToJSON aggParams - | Min aggParams -> "min", AggParamsToJSON aggParams - | Sum aggParams -> "sum", AggParamsToJSON aggParams - | Stats aggParams -> "stats", AggParamsToJSON aggParams - | AggTerms aggParams -> "terms", AggParamsToJSON aggParams - | AggDateHistogram aggParams -> "date_histogram", AggParamsToJSON aggParams - "\"" + aggName + "\":{" + aggBody + "}" - ) - + "}" - -let rec AggsBodyToJSON (fields: AggsFieldsBody list) = - [ - for field in fields -> - match field with - | NamedAgg (name, agg) -> - AggBodyToJSON (name, agg) - | MoreAggs aggs -> - "\"aggs\":{" + (AggsBodyToJSON aggs) + "}" - | FilterAgg (name, query, agg) -> - let queryBody = Query.QueryBodyToJson query - let aggBody = AggBodyToJSON (name, agg) - "\"" + name + "\":{\"filter\":" + queryBody + ",\"aggs\":{" + aggBody + "}}" - ] |> String.concat "," diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Interface.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Interface.fs deleted file mode 100644 index b2187a2..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Interface.fs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Elasticsearch.FSharp.DSL.Serialization - -open Elasticsearch.FSharp.DSL.Serialization.Search - -[] -module Interface = - let ToJson = ElasticDSLToJson \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/MatchPhrasePrefixQuery.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Queries/MatchPhrasePrefixQuery.fs deleted file mode 100644 index 6d43669..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/MatchPhrasePrefixQuery.fs +++ /dev/null @@ -1,18 +0,0 @@ -module Elasticsearch.FSharp.DSL.Serialization.Queries.MatchPhrasePrefixQuery -open Elasticsearch.FSharp.DSL - -let MatchPhrasePrefixQueryToJson ((name, matchBody) : string * (MatchPhrasePrefixQueryField list)) = - "{" + - ( - "\"" + name + "\":{" + - ([ - for matchParam in matchBody -> - match matchParam with - | MatchPhrasePrefixQueryField.MatchQuery null -> "\"query\":\"\"" // TODO: fail here? - | MatchPhrasePrefixQueryField.MatchQuery x -> "\"query\":\"" + x + "\"" - | MatchPhrasePrefixQueryField.MaxExpansions x -> "\"max_expansions\":" + x.ToString() - - ] |> String.concat ",") - + "}" - ) - + "}" \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/MatchQuery.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Queries/MatchQuery.fs deleted file mode 100644 index 73374f5..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/MatchQuery.fs +++ /dev/null @@ -1,23 +0,0 @@ -module Elasticsearch.FSharp.DSL.Serialization.Queries.MatchQuery - -open Elasticsearch.FSharp.DSL - -let MatchQueryToJson ((name, matchBody) : string * (MatchQueryField list) ) = - "{" + - ( - "\"" + name + "\":{" + - ([ - for matchParam in matchBody -> - match matchParam with - | Operator x -> - "\"operator\":\"" + x + "\"" - | MatchQueryField.MatchQuery null -> "\"query\":\"\"" // TODO: fail here? - | MatchQueryField.MatchQuery x -> "\"query\":\"" + x + "\"" - | CutoffFrequency x -> - "\"cutoff_frequency\":" + x.ToString() - | ZeroTermsQuery x -> - "\"zero_terms_query\":" + x.ToString() - ] |> String.concat ",") - + "}" - ) - + "}" diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/MultiMatchQuery.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Queries/MultiMatchQuery.fs deleted file mode 100644 index e75e689..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/MultiMatchQuery.fs +++ /dev/null @@ -1,20 +0,0 @@ -module Elasticsearch.FSharp.DSL.Serialization.Queries.MultiMatchQuery - -open Elasticsearch.FSharp.DSL - -let MultimatchBodyToJson multimatchBody = - "{" + - ([ - for field in multimatchBody -> - match field with - | QueryType queryType -> "\"type\":\"" + queryType + "\"" - | Fields fieldList -> - ("\"fields\":[" + (List.map (fun s -> "\"" + s + "\"") fieldList |> String.concat ",") + "]") - | MultiMatchQuery null -> "\"query\":\"\"" // TODO: fail here? - | MultiMatchQuery query -> "\"query\":\"" + query + "\"" - | MultiMatchQueryField.MaxExpansions cnt -> """"max_expansions":""" + cnt.ToString() - | Slop cnt -> """"slop":""" + cnt.ToString() - | TieBreaker tie -> """"tie_breaker":""" + tie.ToString() - | MultiMatchQueryField.MultiMatchRaw (key, value) -> "\""+key+"\":" + value - ] |> String.concat ",") - + "}" \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/RangeQuery.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Queries/RangeQuery.fs deleted file mode 100644 index c878f3e..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/RangeQuery.fs +++ /dev/null @@ -1,25 +0,0 @@ -module Elasticsearch.FSharp.DSL.Serialization.Queries.RangeQuery - -open Elasticsearch.FSharp.DSL - -let RangeQueryToJson ((name, rangeBody): string * (RangeQueryField list) ) = - "{" + - ( - "\"" + name + "\":{" + - ([ - for rangeParam in rangeBody -> - match rangeParam with - | Gte x -> - "\"gte\":\"" + x + "\"" - | Gt x -> - "\"gt\":\"" + x + "\"" - | Lte x -> - "\"lte\":\"" + x + "\"" - | Lt x -> - "\"lt\":\"" + x + "\"" - | RangeTimeZone x -> - "\"time_zone\":\"" + x + "\"" - ] |> String.concat ",") - + "}" - ) - + "}" \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/ScriptQuery.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Queries/ScriptQuery.fs deleted file mode 100644 index 9f40bb7..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/ScriptQuery.fs +++ /dev/null @@ -1,11 +0,0 @@ -module Elasticsearch.FSharp.DSL.Serialization.Queries.ScriptQuery - -open Elasticsearch.FSharp.DSL -open Elasticsearch.FSharp.DSL.Serialization.Script - -let ScriptQueryToJson (scriptBody:ScriptField list) = - "{" + - ( - "\"script\":{" + (ScriptFieldsToJSON scriptBody) + "}" - ) - + "}" \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/TermQuery.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Queries/TermQuery.fs deleted file mode 100644 index 718463b..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/TermQuery.fs +++ /dev/null @@ -1,16 +0,0 @@ -module internal Elasticsearch.FSharp.DSL.Serialization.Queries.TermQuery - -open Elasticsearch.FSharp.DSL - -let TermQueryToJson ((name, termBody) : string * (TermQueryField list) ) = - "{" + - ( - "\"" + name + "\":" + - ([ - for termParam in termBody-> - match termParam with - | ExactValue null -> "{\"value\":\"\"}" // TODO: fail here? - | ExactValue x -> "{\"value\":\"" + x + "\"}" - ] |> String.concat ",") - ) - + "}" \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/TermsQuery.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Queries/TermsQuery.fs deleted file mode 100644 index d8e8bba..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Queries/TermsQuery.fs +++ /dev/null @@ -1,24 +0,0 @@ -module Elasticsearch.FSharp.DSL.Serialization.Queries.TermsQuery - -open Elasticsearch.FSharp.DSL - -let TermsQueryToJson ((name, termsBody) : string * (TermsQueryField list)) = - "{" + - ( - "\"" + name + "\":" + - ( - match termsBody with - | [ ValueList x ] -> - "[" + (x |> List.map (fun x -> "\"" + x + "\"") |> String.concat ",") + "]" - | [ FromIndex (index, _type, id, path) ] -> - "{" + - "\"index\":\"" + index + "\"," + - "\"type\":\"" + _type + "\"," + - "\"id\":\"" + id + "\"," + - "\"path\":\"" + path+ "\"" + - "}" - | _ -> - "_error_" - ) - ) - + "}" \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Query.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Query.fs deleted file mode 100644 index 5debf88..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Query.fs +++ /dev/null @@ -1,72 +0,0 @@ -module internal rec Elasticsearch.FSharp.DSL.Serialization.Query - -open Elasticsearch.FSharp.DSL -open Elasticsearch.FSharp.DSL.Serialization.Queries - -let BoolQueryToJson boolQueryBody = - "{" + - ([ - for boolPart in boolQueryBody -> - match boolPart with - | Must queryBody -> - let body = QueryBodyListToJsonBool queryBody - "\"must\":" + body - | Filter queryBody -> - let body = QueryBodyListToJsonBool queryBody - "\"filter\":" + body - | Should queryBody -> - let body = QueryBodyListToJsonBool queryBody - "\"should\":" + body - | MustNot queryBody -> - let body = QueryBodyListToJsonBool queryBody - "\"must_not\":" + body - | MinimumShouldMatch x -> - "\"minimum_should_match\":\"" + x.ToString() + "\"" - ] |> String.concat ",") - + "}" - -let QueryBodyToJson (queryPart: QueryBody) = - "{" + - match queryPart with - | MatchAll -> - "\"match_all\":{}" - | MatchNone -> - "\"match_none\":{}" - | IDs ids -> - "\"ids\":" + "{\"values\":[" + (ids |> List.map (fun x -> "\"" + x + "\"") |> String.concat ",") + "]}" - | Bool boolQuery -> - let body = BoolQueryToJson boolQuery - "\"bool\":" + body - | Match matchQuery -> - let body = MatchQuery.MatchQueryToJson matchQuery - "\"match\":" + body - | Term termQuery -> - let body = TermQuery.TermQueryToJson termQuery - "\"term\":" + body - | Terms termsQuery -> - let body = TermsQuery.TermsQueryToJson termsQuery - "\"terms\":" + body - | Range rangeQuery -> - let body = RangeQuery.RangeQueryToJson rangeQuery - "\"range\":" + body - | Script scriptQuery -> - let body = ScriptQuery.ScriptQueryToJson scriptQuery - "\"script\":" + body - | MultiMatch multimatchBody -> - let body = MultiMatchQuery.MultimatchBodyToJson multimatchBody - "\"multi_match\":" + body - | MatchPhrasePrefix matchPhrasePrefixBody -> - let body = MatchPhrasePrefixQuery.MatchPhrasePrefixQueryToJson matchPhrasePrefixBody - "\"match_phrase_prefix\":" + body - | Exists field -> - "\"exists\":{\"field\":\"" + field + "\"}" - | TypeEquals t -> - "\"type\":{\"value\":\"" + t + "\"}" - | QueryBody.Raw body -> - body - + "}" - -let QueryBodyListToJsonList = List.map QueryBodyToJson - -let QueryBodyListToJsonBool (queryBody: QueryBody list) = - "[" + ( QueryBodyListToJsonList queryBody |> String.concat "," ) + "]" \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Script.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Script.fs deleted file mode 100644 index a0c729e..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Script.fs +++ /dev/null @@ -1,27 +0,0 @@ -module internal Elasticsearch.FSharp.DSL.Serialization.Script - -open Elasticsearch.FSharp.DSL - -let ScriptFieldsToJSON (scriptBody:ScriptField list) = - ([ - for rangeParam in scriptBody -> - match rangeParam with - | Source x -> - "\"source\":\"" + x + "\"" - | Lang x -> - "\"lang\":\"" + x + "\"" - | ScriptId x -> - "\"id\":\"" + x + "\"" - | Params x -> - let x = x |> List.map (fun (k, v) -> "\"" + k + "\":" + "\"" + v + "\"") |> String.concat "," - "\"params\":{" + x + "}" - ] |> String.concat ",") - -let ScriptToJson ((name, scriptBody): ScriptFieldsBody) = - "\"" + name + "\":{\"script\":{" + (ScriptFieldsToJSON scriptBody) + "}}" - -let ScriptFieldsBodyToJSON (fields: ScriptFieldsBody list) = - [ - for field in fields -> - ScriptToJson field - ] |> String.concat "," \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Search.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Search.fs deleted file mode 100644 index 97e569f..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Search.fs +++ /dev/null @@ -1,31 +0,0 @@ -module internal Elasticsearch.FSharp.DSL.Serialization.Search - -open Elasticsearch.FSharp.DSL - -let ElasticDSLToJson (Search elasticBody:ElasticDSL) = - "{" + - ([ - for searchBody in elasticBody -> - match searchBody with - | Query queryBody -> - let body = Query.QueryBodyToJson queryBody - "\"query\":" + body - | Sort sortBody -> - let body = Sort.SortBodyListToJson sortBody - "\"sort\":" + body - | ScriptFields fields -> - let body = Script.ScriptFieldsBodyToJSON fields - "\"script_fields\":{" + body + "}" - | Aggs fields -> - let body = Aggs.AggsBodyToJSON fields - "\"aggs\":{" + body + "}" - | From x -> - "\"from\":" + x.ToString() - | Size x -> - "\"size\":" + x.ToString() - | Source_ x -> - "\"_source\":" + Source.SourceBodyToJSON x - | Raw (key, value) -> - "\""+key+"\":" + value - ] |> String.concat ",") - + "}" \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Sort.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Sort.fs deleted file mode 100644 index 2dc7541..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Sort.fs +++ /dev/null @@ -1,37 +0,0 @@ -module internal Elasticsearch.FSharp.DSL.Serialization.Sort - -open Elasticsearch.FSharp.DSL - -let SortModeToJson (sortMode:SortMode) = - match sortMode with - | SortMode.Min -> "\"min\"" - | SortMode.Max -> "\"max\"" - | SortMode.Sum -> "\"sum\"" - | SortMode.Avg -> "\"avg\"" - | SortMode.Median -> "\"median\"" - -let SortOrderToJson sortOrder = - match sortOrder with - | SortOrder.Asc -> "\"asc\"" - | SortOrder.Desc -> "\"desc\"" - -let internal SortFieldListToJson (sortFieldList : SortField list ) = - "{" + - ([ - for field in sortFieldList -> - match field with - | Order orderVal -> - "\"order\":" + (SortOrderToJson orderVal) - | Mode modeVal -> - "\"mode\":" + (SortModeToJson modeVal) - ] |> String.concat ",") - + "}" - -let internal SortBodyListToJson (sortBody:(string * (SortField list)) list) = - "[" + - ([ - for (name, fields) in sortBody -> - let body = SortFieldListToJson fields - "{\"" + name + "\":" + body + "}" - ] |> String.concat ",") - + "]" \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Serialization/Source.fs b/src/Elasticsearch.FSharp/DSL/Serialization/Source.fs deleted file mode 100644 index 6466006..0000000 --- a/src/Elasticsearch.FSharp/DSL/Serialization/Source.fs +++ /dev/null @@ -1,17 +0,0 @@ -module internal Elasticsearch.FSharp.DSL.Serialization.Source - -open Elasticsearch.FSharp.DSL - -let SerializeList l = - "[" + (l |> List.map (fun field -> "\"" + field + "\"") |> String.concat ",") + "]" - -let SourceBodyToJSON (body: SourceBody) : string = - match body with - | Nothing -> - "false" - | Only str -> - "\"" + str + "\"" - | List l -> - SerializeList l - | Pattern (i, e) -> - "{\"includes\":" + SerializeList i + ", \"excludes\":" + SerializeList e + "}" \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Sort.fs b/src/Elasticsearch.FSharp/DSL/Sort.fs deleted file mode 100644 index 11b4c04..0000000 --- a/src/Elasticsearch.FSharp/DSL/Sort.fs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type SortBody = string * (SortField list) - -and SortField = - | Order of SortOrder - | Mode of SortMode - -and - [] - SortOrder = - | Asc - | Desc - -and - [] - SortMode = - | Min - | Max - | Sum - | Avg - | Median \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/DSL/Source.fs b/src/Elasticsearch.FSharp/DSL/Source.fs deleted file mode 100644 index b7661e0..0000000 --- a/src/Elasticsearch.FSharp/DSL/Source.fs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Elasticsearch.FSharp.DSL - -type Includes = string list -type Excludes = string list - -type SourceBody = - | Nothing - | Only of string - | List of string list - | Pattern of includes:Includes * excludes:Excludes \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/Elasticsearch.FSharp.fsproj b/src/Elasticsearch.FSharp/Elasticsearch.FSharp.fsproj index ac46e3e..0b926f8 100644 --- a/src/Elasticsearch.FSharp/Elasticsearch.FSharp.fsproj +++ b/src/Elasticsearch.FSharp/Elasticsearch.FSharp.fsproj @@ -1,48 +1,22 @@  - - netstandard2.0 - - - - Elasticsearch.FSharp - 1.2.1 - lkmfwe and contributors - No company - + + netstandard2.0 + Elasticsearch.FSharp + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - + + + diff --git a/src/Elasticsearch.FSharp/Mapping/ElasticMapping.fs b/src/Elasticsearch.FSharp/Mapping/ElasticMapping.fs deleted file mode 100644 index 87454a2..0000000 --- a/src/Elasticsearch.FSharp/Mapping/ElasticMapping.fs +++ /dev/null @@ -1,292 +0,0 @@ -namespace Elasticsearch.FSharp -open System - -module Mapping = - - open System.Runtime.InteropServices - open System.Collections.Generic - - - type ElasticType ( - typeName:string, - [] allEnabled:bool - ) = - inherit System.Attribute() - - member val TypeName = typeName with get - member val AllEnabled = allEnabled with get - - type ElasticField( - [] fieldType:string, - [] analyzer:string, - [] enabled:bool, - [] format:string, - [] useProperties:bool, - [] maxDepth:int - ) = - inherit System.Attribute() - - member val FieldType = fieldType with get - member val Analyzer = analyzer with get - member val Enabled = enabled with get - member val Format = format with get - member val UseProperties = useProperties with get - member val MaxDepth = maxDepth with get - - [] - type ElasticSubField( - fieldName: string, - [] fieldType:string, - [] analyzer:string, - [] enabled:bool, - [] format:string, - [] useProperties:bool, - [] maxDepth:int - ) = - inherit ElasticField(fieldType, analyzer, enabled, format, useProperties, maxDepth) - - member val FieldName = fieldName with get - - module rec ElasticMappingDSL = - type ElasticMapping = - | ElasticMapping of ElasticMappingBody list - - and ElasticMappingBody = - | Settings of SettingsBody list - | Mappings of TypeMapping list - - and SettingsBody = - | Setting of string*string - | BoolSetting of string*bool - - and TypeMapping = - string * (TypeMappingBody list) - - and TypeMappingBody = - | AllEnabled of bool - | TypeProperties of PropertyMapping list - - and PropertyMapping = string * (PropertyMappingField list) - - and PropertyMappingField = - | Type of string - | Analyzer of string - | Enabled of bool - | Format of string - | Properties of PropertyMapping list - | Fields of PropertyMapping list - - let internal SettingsBodyListToJSON settingsBody = - "{" + - ([ - for sb in settingsBody -> - match sb with - | Setting (k, v) -> - "\""+k+"\":" + "\""+v+"\"" - | BoolSetting (k, v) -> - "\""+k+"\":" + if v then "true" else "false" - ] |> String.concat ",") - + "}" - - let internal PropertyMappingFieldListToJSON propertyMappingFields = - "{" + - ([ - for pmf in propertyMappingFields do - match pmf with - | Type v -> - yield "\"type\":\"" + v + "\"" - | Analyzer v -> - yield "\"analyzer\":\"" + v + "\"" - | Enabled v -> - yield "\"enabled\":" + (if v then "true" else "false") - | Format v -> - yield "\"format\":\"" + v + "\"" - | Properties v -> - yield "\"properties\":{" + (PropertyMappingListToJSON v) + "}" - | Fields v-> - match v with - | [] -> - () - | _ -> - yield "\"fields\":{" + (PropertyMappingListToJSON v) + "}" - ] |> String.concat ",") - + "}" - - let internal PropertyMappingListToJSON propertyMappings = - ([ - for (fieldName, pmf) in propertyMappings -> - "\"" + fieldName + "\":" + (PropertyMappingFieldListToJSON pmf) - ] |> String.concat ",") - - let internal TypeMappingBodyListToJSON typeMappingsBody = - "{" + - ([ - for tm in typeMappingsBody -> - match tm with - | AllEnabled v -> - "\"_all\":{\"enabled\":" + (if v then "true" else "false") + "}" - | TypeProperties propertyMappings -> - "\"properties\":{" + PropertyMappingListToJSON propertyMappings + "}" - ] |> String.concat ",") - + "}" - - let internal MappingsBodyListToJSON mappingsBody = - "{" + - ([ - for (typeName, typeMappingsBody) in mappingsBody -> - "\"" + typeName + "\":" + (TypeMappingBodyListToJSON typeMappingsBody) - ] |> String.concat ",") - + "}" - - let internal ElasticMappingBodyListToJSON mappingBodies = - [ - for mb in mappingBodies -> - match mb with - | Settings settingsBody -> - "\"settings\":" + (SettingsBodyListToJSON settingsBody) - | Mappings mappingsBody -> - "\"mappings\":" + (MappingsBodyListToJSON mappingsBody) - ] |> String.concat "," - - let private PrevPropNameDefault propMapping = [propMapping] - - let rec private GetSingularTypePropertiesMappings - (prevPropName:PropertyMapping -> PropertyMapping list) - (propMappings: PropertyMapping list) - (outContainer: ref>) = - for (propName, propDef) in propMappings do - let mutable hasProperties = false - for propMappingField in propDef do - match propMappingField with - | Properties props -> - hasProperties <- true - let fn propMapping = prevPropName (propName, [Properties [propMapping]]) - GetSingularTypePropertiesMappings fn props outContainer - | _ -> () - if not <| hasProperties then - outContainer.Value.Add(prevPropName (propName, propDef)) - - let ElasticMappingToPutMappingJSON mapping = - [ - match mapping with - | ElasticMapping mappingBody -> - for mb in mappingBody do - match mb with - | Mappings mappingsBody -> - for (typeName, typeMappingsBody) in mappingsBody do - for tm in typeMappingsBody do - match tm with - | TypeProperties propertyMappings -> - let propList = ref (new List()) - GetSingularTypePropertiesMappings PrevPropNameDefault propertyMappings propList - for propertyMappings in propList.Value do - yield - "{\"properties\":{" + PropertyMappingListToJSON propertyMappings + "}}" - | _ -> () - - | _ -> () - ] - - let ElasticMappingToJSON mapping = - "{" + - match mapping with - | ElasticMapping mappingBody -> - ElasticMappingBodyListToJSON mappingBody - + "}" - - open ElasticMappingDSL - - let private typeofElasticType = typeof - - let rec private GetRealType (t:System.Type) : System.Type = - if t.IsArray then - GetRealType (t.GetElementType()) - else if t.Name = typeof>.Name then - GetRealType t.GenericTypeArguments.[0] - else - t - - let rec FieldToMapping (propAttr: ElasticField) : PropertyMappingField list = - (seq { - if propAttr.Enabled then - yield PropertyMappingField.Type propAttr.FieldType - - if not <| String.IsNullOrWhiteSpace propAttr.Analyzer then - yield Analyzer propAttr.Analyzer - - if not propAttr.Enabled then - yield Enabled false - - if not <| String.IsNullOrWhiteSpace propAttr.Format then - yield Format propAttr.Format - - } |> Seq.toList) - - exception UnknownElasticAttributeException of System.Type - - let rec private GetTypePropertyMappings (t:System.Type) (depth:int) : PropertyMapping list = - [ - for prop in t.GetProperties() do - let propAttributes = prop.GetCustomAttributes(typeof, true) - let propType = prop.PropertyType - - let props = - [ - for propAttr in propAttributes do - match propAttr with - | :? ElasticSubField -> - () - | :? ElasticField as propAttr -> - if propAttr.UseProperties then - if depth < propAttr.MaxDepth then - let subTypeProps = GetTypePropertyMappings (GetRealType propType) (depth+1) - yield - Properties subTypeProps - else - yield! (propAttr |> FieldToMapping) - | _ -> - raise(UnknownElasticAttributeException(propAttr.GetType())) - ] - - if props.Length > 0 then - let fields = - propAttributes - |> Array.choose (fun a -> match a with | :? ElasticSubField as f -> Some f | _ -> None) - |> Array.map - (fun propAttr -> - propAttr.FieldName, propAttr |> FieldToMapping - ) - |> Array.toList - - yield prop.Name, [ - if fields.Length > 0 then - yield fields |> Fields - yield! props - ] - ] - - exception IsNotElasticTypeException of System.Type - - let GetTypeIndexName (t:System.Type) = - let propAttributes = t.GetCustomAttributes(typeofElasticType, true) - let propAttr = Array.tryHead propAttributes - match propAttr with - | Some propAttr -> - let propAttr = propAttr :?> ElasticType - propAttr.TypeName - | None -> - raise (IsNotElasticTypeException t) - - let GenerateElasticMappings(t:System.Type) : TypeMapping = - let attrs = t.GetCustomAttributes(typeofElasticType, true) - let attr = Array.tryHead attrs - match attr with - | Some attr -> - let attr = attr :?> ElasticType - let propertyMappings = GetTypePropertyMappings t 0 - - attr.TypeName, [ - TypeMappingBody.TypeProperties propertyMappings - ] - | None -> - raise (System.Exception "ElasticType attribute not found!") \ No newline at end of file diff --git a/src/Elasticsearch.FSharp/TopLevelModule.fs b/src/Elasticsearch.FSharp/TopLevelModule.fs new file mode 100644 index 0000000..9ccc24c --- /dev/null +++ b/src/Elasticsearch.FSharp/TopLevelModule.fs @@ -0,0 +1,15 @@ +module Elasticsearch.FSharp.Module + +open Elasticsearch.FSharp.Builders + +let elastic<'T when 'T: not struct>() = ElasticBuilder<'T>() + +let match_all() = Query.MatchAllBuilder().Zero() + +let bool<'T when 'T: not struct> = Query.BoolBuilder<'T>() + +let agg name = Aggs.AggBuilder name + +let terms = Aggs.TermsBuilder() + +let sortBy = Sort.SortByBuilder() \ No newline at end of file diff --git a/tests/Elasticsearch.FSharp.Tests/Elasticsearch.FSharp.Tests.fsproj b/tests/Elasticsearch.FSharp.Tests/Elasticsearch.FSharp.Tests.fsproj index 1fae2d7..2d2cece 100644 --- a/tests/Elasticsearch.FSharp.Tests/Elasticsearch.FSharp.Tests.fsproj +++ b/tests/Elasticsearch.FSharp.Tests/Elasticsearch.FSharp.Tests.fsproj @@ -1,29 +1,23 @@  - netcoreapp2.2 + netcoreapp2.1;netcoreapp3.1 + Elasticsearch.FSharp.Tests - - - - - + + - - - - - - - + - + + + - \ No newline at end of file + diff --git a/tests/Elasticsearch.FSharp.Tests/Helper.fs b/tests/Elasticsearch.FSharp.Tests/Helper.fs new file mode 100644 index 0000000..16fb970 --- /dev/null +++ b/tests/Elasticsearch.FSharp.Tests/Helper.fs @@ -0,0 +1,17 @@ +module Elasticsearch.FSharp.Tests.Helper + +open System.IO +open Nest +open Xunit + +let elasticClient = ElasticClient() +let serializeToString (searchRequest: ISearchRequest) = + use outputStream = new MemoryStream() + elasticClient.SourceSerializer.Serialize(searchRequest, outputStream) + outputStream.Seek(0L, SeekOrigin.Begin) |> ignore + use sr = new StreamReader(outputStream) + sr.ReadToEnd() + +type Assert with + static member EqualQuery(expected: ISearchRequest, actual: ISearchRequest) = + Assert.Equal(serializeToString expected, serializeToString actual) diff --git a/tests/Elasticsearch.FSharp.Tests/Helpers.fs b/tests/Elasticsearch.FSharp.Tests/Helpers.fs deleted file mode 100644 index 7f8ec01..0000000 --- a/tests/Elasticsearch.FSharp.Tests/Helpers.fs +++ /dev/null @@ -1,6 +0,0 @@ -module internal Elasticsearch.FSharp.Tests.Helpers - -open System.Text.RegularExpressions - -let removeWhitespace s = - Regex.Replace(s, "\s+", System.String.Empty) \ No newline at end of file diff --git a/tests/Elasticsearch.FSharp.Tests/Mapping.fs b/tests/Elasticsearch.FSharp.Tests/Mapping.fs deleted file mode 100644 index 8e1f810..0000000 --- a/tests/Elasticsearch.FSharp.Tests/Mapping.fs +++ /dev/null @@ -1,133 +0,0 @@ -module Elasticsearch.FSharp.Tests.Mapping - -open NUnit.Framework - -open System.Text.RegularExpressions -open System.Text.RegularExpressions -open Elasticsearch.FSharp.Mapping -open Elasticsearch.FSharp.Mapping.ElasticMappingDSL - -[] -type TestEntity = { - [] - id: int64 - - [] - [] - [] - [] - title: string -} - - -[] -let ``Type serializes correctly``() = - let typeMapping = GenerateElasticMappings typeof - let indexMapping = - ElasticMapping [ - Mappings [ - typeMapping - ] - ] - let mappingJson = ElasticMappingToJSON indexMapping - let expected = - Regex.Replace( - """{ - "mappings": { - "custom_entity_name": { - "properties": { - "id": { - "type": "long" - }, - "title": { - "fields": { - "raw": { "type":"keyword" }, - "en": { "type":"text", "analyzer":"english" }, - "ru": { "type":"text", "analyzer":"russian" } - }, - "type": "text" - } - } - } - } - }""", - "\s*", - "" - ) - let actual = mappingJson - printf "%s" mappingJson - Assert.AreEqual(expected, actual) - -[] -type Elastic_Message = { - [] - [] - [] - [] - id: string - - [] - reply_to_message: Elastic_Message option -} - -[] -let ``Recursive type serializes correctly``() = - let typeMapping = GenerateElasticMappings typeof - let indexMapping = - ElasticMapping [ - Mappings [ - typeMapping - ] - ] - let mappingJson = ElasticMappingToJSON indexMapping - let expected = - Regex.Replace( - """{ - "mappings": { - "message": { - "properties": { - "id": { - "fields": { - "raw": { - "type": "keyword" - }, - "ru": { - "type": "text", - "analyzer": "ru" - }, - "en": { - "type": "text", - "analyzer": "en" - } - }, - "type": "keyword" - }, - "reply_to_message": { - "properties": { - "id": { - "fields": { - "raw": { - "type": "keyword" - }, - "ru": { - "type": "text", - "analyzer": "ru" - }, - "en": { - "type": "text", - "analyzer": "en" - } - }, - "type": "keyword" - } - } - } - } - } - } - }""", - "\s*", - "") - let actual = mappingJson - printf "%s" mappingJson - Assert.AreEqual(expected, actual) \ No newline at end of file diff --git a/tests/Elasticsearch.FSharp.Tests/Queries/ScriptQuery.fs b/tests/Elasticsearch.FSharp.Tests/Queries/ScriptQuery.fs deleted file mode 100644 index 9cd6fb1..0000000 --- a/tests/Elasticsearch.FSharp.Tests/Queries/ScriptQuery.fs +++ /dev/null @@ -1,20 +0,0 @@ -module Elasticsearch.FSharp.Tests.Queries.ScriptQuery - -open Elasticsearch.FSharp.DSL -open Elasticsearch.FSharp.DSL.Serialization -open FsCheck.NUnit - -[] -let ``"script" query serializes correctly`` scriptSource scriptLang = - let query = - Search [ - Query ( - Script [ - Source scriptSource - Lang scriptLang - ] - ) - ] - let expected = sprintf """{"query":{"script":{"script":{"source":"%s","lang":"%s"}}}}""" scriptSource scriptLang - let actual = ToJson query - expected = actual \ No newline at end of file diff --git a/tests/Elasticsearch.FSharp.Tests/Query.fs b/tests/Elasticsearch.FSharp.Tests/Query.fs deleted file mode 100644 index b875773..0000000 --- a/tests/Elasticsearch.FSharp.Tests/Query.fs +++ /dev/null @@ -1,186 +0,0 @@ -module Elasticsearch.FSharp.Tests.Query - -open NUnit.Framework -open FsCheck.NUnit -open Elasticsearch.FSharp.DSL -open Elasticsearch.FSharp.DSL.Serialization - -[] -let ``"match_all" serializes correctly``() = - let query = - Search [ - Query MatchAll - ] - let expected = """{"query":{"match_all":{}}}""" - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``"match_none" serializes correctly``() = - let query = - Search [ - Query MatchNone - ] - let expected = """{"query":{"match_none":{}}}""" - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``"ids" serializes correctly``() = - let query = - Search [ - Query (IDs ["foo"; "bar"]) - ] - let expected = """{"query":{"ids":{"values":["foo","bar"]}}}""" - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``"bool" serializes correctly``() = - let query = - Search [ - Query ( - Bool [ - Must [ - MatchAll - ] - ] - ) - ] - let expected = """{"query":{"bool":{"must":[{"match_all":{}}]}}}""" - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``"match" serializes correctly``(fieldName, fieldValue) = - let query = - Search [ - Query ( - Match (fieldName, [MatchQuery fieldValue]) - ) - ] - let expected = sprintf """{"query":{"match":{"%s":{"query":"%s"}}}}""" fieldName fieldValue - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``"term" serializes correctly``(fieldName, fieldValue) = - let query = - Search [ - Query ( - Term (fieldName, [ExactValue fieldValue]) - ) - ] - let expected = sprintf """{"query":{"term":{"%s":{"value":"%s"}}}}""" fieldName fieldValue - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``"terms" serializes correctly``(fieldName, fieldValue) = - let query = - Search [ - Query ( - Terms (fieldName, [ValueList [fieldValue]]) - ) - ] - let expected = sprintf """{"query":{"terms":{"%s":["%s"]}}}""" fieldName fieldValue - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``"range" serializes correctly``(fieldName, fieldValue) = - let query = - Search [ - Query ( - Range (fieldName, [Gte fieldValue]) - ) - ] - let expected = sprintf """{"query":{"range":{"%s":{"gte":"%s"}}}}""" fieldName fieldValue - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``"script" serializes correctly``(scriptSource) = - let query = - Search [ - Query ( - Script [Lang "painless"; Source scriptSource] - ) - ] - let expected = sprintf """{"query":{"script":{"script":{"lang":"painless","source":"%s"}}}}""" scriptSource - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -// TODO don't know how to specify range for tie_breaker value (by default values from -Infinity to Infinity are generated) -let ``"multi_match" serializes correctly``(queryType, field, queryString, expansions, slop) = - let query = - Search [ - Query ( - MultiMatch [ - QueryType queryType - Fields [field] - MultiMatchQuery queryString - MaxExpansions expansions - Slop slop - TieBreaker 0.3 - ] - ) - ] - let expected = sprintf """{"query":{"multi_match":{"type":"%s","fields":["%s"],"query":"%s","max_expansions":%d,"slop":%d,"tie_breaker":0.3}}}""" queryType field queryString expansions slop - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``"match_phrase_prefix* serializes correctly`` (fieldName, fieldValue, expansions) = - let query = - Search [ - Query ( - MatchPhrasePrefix ( - fieldName, - [ - MatchPhrasePrefixQueryField.MatchQuery fieldValue - MatchPhrasePrefixQueryField.MaxExpansions expansions - ] - ) - ) - ] - let expected = sprintf """{"query":{"match_phrase_prefix":{"%s":{"query":"%s","max_expansions":%d}}}}""" fieldName fieldValue expansions - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``"exists" serialization works correctly``(fieldName) = - let query = - Search [ - Query( - Exists fieldName - ) - ] - let expected = sprintf """{"query":{"exists":{"field":"%s"}}}""" fieldName - let actual = ToJson query - expected = actual - -[] -let ``"raw" serialization works correctly``(rawQuery) = - let query = - Search [ - Query( - QueryBody.Raw rawQuery - ) - ] - let expected = sprintf """{"query":{%s}}""" rawQuery - let actual = ToJson query - expected = actual - -[] -let ``"type" serializes correctly``(``type``) = - let query = - Search [ - Query ( - TypeEquals ``type`` - ) - ] - let expected = sprintf """{"query":{"type":{"value":"%s"}}}""" ``type`` - let actual = ToJson query - Assert.AreEqual(expected, actual) \ No newline at end of file diff --git a/tests/Elasticsearch.FSharp.Tests/Script.fs b/tests/Elasticsearch.FSharp.Tests/Script.fs deleted file mode 100644 index d1da925..0000000 --- a/tests/Elasticsearch.FSharp.Tests/Script.fs +++ /dev/null @@ -1,2 +0,0 @@ -module Elasticsearch.FSharp.Tests.Script - diff --git a/tests/Elasticsearch.FSharp.Tests/Search.fs b/tests/Elasticsearch.FSharp.Tests/Search.fs deleted file mode 100644 index 901c8f1..0000000 --- a/tests/Elasticsearch.FSharp.Tests/Search.fs +++ /dev/null @@ -1,116 +0,0 @@ -module Elasticsearch.FSharp.Tests.Search - -open NUnit.Framework -open FsCheck.NUnit - -open Elasticsearch.FSharp.DSL -open Elasticsearch.FSharp.DSL.Serialization - -[] -let ``Query serializes correctly``() = - let query = - Search [ - Query MatchAll - ] - let expected = """{"query":{"match_all":{}}}""" - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``Sort serializes correctly``() = - let query = - Search [ - Sort [ - "myField", [Order SortOrder.Asc; Mode SortMode.Avg] - ] - ] - let expected = """{"sort":[{"myField":{"order":"asc","mode":"avg"}}]}""" - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``ScriptFields serializes correctly``(script1, script2, fieldName1, fieldName2, paramName, paramValue) = - let query = - Search [ - ScriptFields [ - fieldName1, [ - Lang "painless" - Source script1 - ] - fieldName2, [ - Lang "painless" - Source script2 - Params [ - paramName, paramValue - ] - ] - ] - ] - let expected = - sprintf - """{"script_fields":{"%s":{"script":{"lang":"painless","source":"%s"}},"%s":{"script":{"lang":"painless","source":"%s","params":{"%s":"%s"}}}}}""" - fieldName1 - script1 - fieldName2 - script2 - paramName - paramValue - - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``Aggs serializes correctly``(aggName, aggFieldName) = - let query = - Search [ - Aggs [ - NamedAgg ( - aggName, Avg [ - AggField aggFieldName - ] - ) - ] - ] - let expected = sprintf """{"aggs":{"%s":{"avg":{"field":"%s"}}}}""" aggName aggFieldName - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``From serializes correctly``(from) = - let query = - Search [ - From from - ] - let expected = sprintf """{"from":%d}""" from - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``Size serializes correctly``(size) = - let query = - Search [ - Size size - ] - let expected = sprintf """{"size":%d}""" size - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``Source serializes correctly``() = - let query = - Search [ - Source_ Nothing - ] - let expected = """{"_source":false}""" - let actual = ToJson query - Assert.AreEqual(expected, actual) - -[] -let ``Raw serialized correctly``() = - let query = - Search [ - SearchBody.Raw ("query", """{"match_all":{}}""") - ] - let expected = """{"query":{"match_all":{}}}""" - let actual = ToJson query - Assert.AreEqual(expected, actual) \ No newline at end of file diff --git a/tests/Elasticsearch.FSharp.Tests/Sort.fs b/tests/Elasticsearch.FSharp.Tests/Sort.fs deleted file mode 100644 index 46d1cd7..0000000 --- a/tests/Elasticsearch.FSharp.Tests/Sort.fs +++ /dev/null @@ -1,32 +0,0 @@ -module Elasticsearch.FSharp.Tests.Sort - -open Elasticsearch.FSharp.DSL -open Elasticsearch.FSharp.DSL.Serialization -open NUnit.Framework -open FsCheck.NUnit - -[] -let ``Sort serializes correctly``(fieldName, sortOrder, sortMode) = - let query = - Search [ - Sort [fieldName, [Order sortOrder; Mode sortMode]] - Query MatchAll - ] - - let orderStr = - match sortOrder with - | SortOrder.Asc -> "asc" - | SortOrder.Desc -> "desc" - - let modeStr = - match sortMode with - | SortMode.Min -> "min" - | SortMode.Max -> "max" - | SortMode.Sum -> "sum" - | SortMode.Avg -> "avg" - | SortMode.Median -> "median" - - let expected = - sprintf """{"sort":[{"%s":{"order":"%s","mode":"%s"}}],"query":{"match_all":{}}}""" fieldName orderStr modeStr - let actual = ToJson query - Assert.AreEqual(expected, actual) \ No newline at end of file diff --git a/tests/Elasticsearch.FSharp.Tests/TopLevelModule.fs b/tests/Elasticsearch.FSharp.Tests/TopLevelModule.fs new file mode 100644 index 0000000..db63e98 --- /dev/null +++ b/tests/Elasticsearch.FSharp.Tests/TopLevelModule.fs @@ -0,0 +1,51 @@ +module Elasticsearch.FSharp.Tests + +open System +open Elasticsearch.FSharp.Module +open Nest +open Xunit +open Elasticsearch.FSharp.Tests.Helper + +[] +let ``Create match all query``() = + let actual = elastic() { + query ( + match_all() + ) + size 10000 + } + let expected = + SearchDescriptor() + .Query(fun q -> q.MatchAll()) + .Size(Nullable 10000) + + Assert.EqualQuery(expected, actual) + +[] +let ``Create bool query``() = + let actual = elastic() { + query ( + bool { + must [ + match_all() + ] + should [ + match_all() + ] + must_not [ + match_all() + ] + minimum_should_match "2.0" + } + ) + } + let expected = + SearchDescriptor() + .Query(fun q -> q.Bool(fun b -> + b.Must(fun (q:QueryContainerDescriptor) -> q.MatchAll()) + .Should(fun (q:QueryContainerDescriptor) -> q.MatchAll()) + .MustNot(fun (q:QueryContainerDescriptor) -> q.MatchAll()) + .MinimumShouldMatch(MinimumShouldMatch("2.0")) + :> IBoolQuery + )) + Assert.EqualQuery(expected, actual) \ No newline at end of file