diff --git a/src/Nest/DSL/Aggregations/CardinalityAggregationDescriptor.cs b/src/Nest/DSL/Aggregations/CardinalityAggregationDescriptor.cs index 6cab05a3c56..7d50cac4728 100644 --- a/src/Nest/DSL/Aggregations/CardinalityAggregationDescriptor.cs +++ b/src/Nest/DSL/Aggregations/CardinalityAggregationDescriptor.cs @@ -13,12 +13,12 @@ public class CardinalityAggregationDescriptor : MetricAggregationBaseDescript where T : class { - [JsonProperty("precision_treshold")] - internal int? _PrecisionTreshold { get; set; } + [JsonProperty("precision_threshold")] + internal int? _PrecisionThreshold { get; set; } - public CardinalityAggregationDescriptor PrecisionTreshold(int precisionTreshold) + public CardinalityAggregationDescriptor PrecisionThreshold(int precisionThreshold) { - this._PrecisionTreshold = precisionTreshold; + this._PrecisionThreshold = precisionThreshold; return this; } diff --git a/src/Nest/DSL/Query/FunctionScoreQueryDescriptor.cs b/src/Nest/DSL/Query/FunctionScoreQueryDescriptor.cs index 33a3c43aee6..4a52b33df12 100644 --- a/src/Nest/DSL/Query/FunctionScoreQueryDescriptor.cs +++ b/src/Nest/DSL/Query/FunctionScoreQueryDescriptor.cs @@ -1,339 +1,413 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using Elasticsearch.Net; -using Nest.Resolvers; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace Nest -{ - //More info about it http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/query-dsl-function-score-query.html - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class FunctionScoreQueryDescriptor : IQuery where T : class - { - [JsonProperty(PropertyName = "functions")] - internal IEnumerable> _Functions { get; set; } - - [JsonProperty(PropertyName = "query")] - internal BaseQuery _Query { get; set; } - - [JsonProperty(PropertyName = "score_mode")] - [JsonConverter(typeof(StringEnumConverter))] - FunctionScoreMode? _ScoreMode { get; set; } - - [JsonProperty(PropertyName = "boost_mode")] - [JsonConverter(typeof(StringEnumConverter))] - FunctionBoostMode? _BoostMode { get; set; } - - [JsonProperty(PropertyName = "random_score")] - RandomScoreFunction _RandomScore { get; set; } - - [JsonProperty(PropertyName = "script_score")] - ScriptFilterDescriptor _ScriptScore { get; set; } - - bool IQuery.IsConditionless - { - get - { - return (this._Query == null || this._Query.IsConditionless) && _RandomScore == null && _ScriptScore == null && (_Functions == null || !_Functions.Any()); - } - } - - public FunctionScoreQueryDescriptor Query(Func, BaseQuery> querySelector) - { - querySelector.ThrowIfNull("querySelector"); - var query = new QueryDescriptor(); - var q = querySelector(query); - - this._Query = q.IsConditionless ? null : q; - return this; - } - - public FunctionScoreQueryDescriptor Functions(params Func, FunctionScoreFunction>[] functions) - { - var descriptor = new FunctionScoreFunctionsDescriptor(); - - foreach (var f in functions) - { - f(descriptor); - } - - _Functions = descriptor; - - return this; - } - - public FunctionScoreQueryDescriptor ScoreMode(FunctionScoreMode mode) - { - this._ScoreMode = mode; - return this; - } - - public FunctionScoreQueryDescriptor BoostMode(FunctionBoostMode mode) - { - this._BoostMode = mode; - return this; - } - - public FunctionScoreQueryDescriptor RandomScore(int? seed=null) - { - this._RandomScore = new RandomScoreFunction(); - if (seed.HasValue) - { - _RandomScore._Seed = seed.Value; - } - return this; - } - - public FunctionScoreQueryDescriptor ScriptScore(Action scriptSelector) - { - var descriptor = new ScriptFilterDescriptor(); - if (scriptSelector != null) - scriptSelector(descriptor); - - this._ScriptScore = descriptor; - - return this; - } - } - - public enum FunctionScoreMode - { - multiply, - sum, - avg, - first, - max, - min - } - - public enum FunctionBoostMode - { - multiply, - replace, - sum, - avg, - max, - min - } - - public class FunctionScoreFunctionsDescriptor : IEnumerable> where T : class - { - internal List> _Functions { get; set; } - - public FunctionScoreFunctionsDescriptor() - { - this._Functions = new List>(); - } - - public FunctionScoreFunction Gauss(Expression> objectPath, Action db) - { - var fn = new GaussFunction(objectPath, db); - this._Functions.Add(fn); - return fn; - } - - public FunctionScoreFunction Linear(Expression> objectPath, Action db) - { - var fn = new LinearFunction(objectPath, db); - this._Functions.Add(fn); - return fn; - } - - public FunctionScoreFunction Exp(Expression> objectPath, Action db) - { - var fn = new ExpFunction(objectPath, db); - this._Functions.Add(fn); - return fn; - } - - public BoostFactorFunction BoostFactor(double value) - { - var fn = new BoostFactorFunction(value); - this._Functions.Add(fn); - return fn; - } - - public ScriptScoreFunction ScriptScore(Action scriptSelector) - { - var fn = new ScriptScoreFunction(scriptSelector); - this._Functions.Add(fn); - return fn; - } - - public IEnumerator> GetEnumerator() - { - return _Functions.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _Functions.GetEnumerator(); - } - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class FunctionScoreFunction - { - } - - public class FunctionScoreDecayFieldDescriptor - { - [JsonProperty(PropertyName = "origin")] - internal string _Origin { get; set; } - - [JsonProperty(PropertyName = "scale")] - internal string _Scale { get; set; } - - [JsonProperty(PropertyName = "offset")] - internal string _Offset { get; set; } - - [JsonProperty(PropertyName = "decay")] - internal double? _Decay { get; set; } - - public FunctionScoreDecayFieldDescriptor Origin(string origin) - { - this._Origin = origin; - return this; - } - - public FunctionScoreDecayFieldDescriptor Scale(string scale) - { - this._Scale = scale; - return this; - } - - public FunctionScoreDecayFieldDescriptor Offset(string offset) - { - this._Offset = offset; - return this; - } - - public FunctionScoreDecayFieldDescriptor Decay(double? decay) - { - this._Decay = decay; - return this; - } - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class FunctionScoreDecayFunction : FunctionScoreFunction - { - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class FunctionScoreFilteredFunction : FunctionScoreFunction where T : class - { - [JsonProperty(PropertyName = "filter")] - internal BaseFilter _Filter { get; set; } - - public FunctionScoreFunction Filter(Func, BaseFilter> filterSelector) - { - filterSelector.ThrowIfNull("filterSelector"); - var filter = new FilterDescriptor(); - var f = filterSelector(filter); - - this._Filter = f; - return this; - } - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class GaussFunction : FunctionScoreDecayFunction - { - [JsonProperty(PropertyName = "gauss")] - [JsonConverter(typeof(DictionaryKeysAreNotPropertyNamesJsonConverter))] - internal IDictionary _GaussDescriptor { get; set; } - - public GaussFunction(Expression> objectPath, Action descriptorBuilder) - { - _GaussDescriptor = new Dictionary(); - - var descriptor = new FunctionScoreDecayFieldDescriptor(); - descriptorBuilder(descriptor); - _GaussDescriptor[objectPath] = descriptor; - } - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class LinearFunction : FunctionScoreDecayFunction - { - [JsonProperty(PropertyName = "linear")] - [JsonConverter(typeof(DictionaryKeysAreNotPropertyNamesJsonConverter))] - internal IDictionary _LinearDescriptor { get; set; } - - public LinearFunction(Expression> objectPath, Action descriptorBuilder) - { - _LinearDescriptor = new Dictionary(); - - var descriptor = new FunctionScoreDecayFieldDescriptor(); - descriptorBuilder(descriptor); - _LinearDescriptor[objectPath] = descriptor; - } - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class ExpFunction : FunctionScoreDecayFunction - { - [JsonProperty(PropertyName = "exp")] - [JsonConverter(typeof(DictionaryKeysAreNotPropertyNamesJsonConverter))] - internal IDictionary _ExpDescriptor { get; set; } - - public ExpFunction(Expression> objectPath, Action descriptorBuilder) - { - _ExpDescriptor = new Dictionary(); - - var descriptor = new FunctionScoreDecayFieldDescriptor(); - descriptorBuilder(descriptor); - _ExpDescriptor[objectPath] = descriptor; - } - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class BoostFactorFunction : FunctionScoreFilteredFunction where T : class - { - [JsonProperty(PropertyName = "boost_factor")] - internal double _BoostFactor { get; set; } - - public BoostFactorFunction(double boostFactor) - { - _BoostFactor = boostFactor; - } - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class ScriptScoreFunction : FunctionScoreFilteredFunction where T : class - { - [JsonProperty(PropertyName = "script_score")] - internal ScriptFilterDescriptor _ScriptScore { get; set; } - - public ScriptScoreFunction(Action scriptSelector) - { - var descriptor = new ScriptFilterDescriptor(); - if (scriptSelector != null) - scriptSelector(descriptor); - - this._ScriptScore = descriptor; - } - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class RandomScoreFunction - { - [JsonProperty(PropertyName = "seed")] - internal int? _Seed { get; set; } - - public RandomScoreFunction(int seed) - { - _Seed = seed; - } - - public RandomScoreFunction() - { - } - } +using Nest.Resolvers; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; + +namespace Nest +{ + //More info about it http://www.elasticsearch.org/guide/en/elasticsearch/reference/master/query-dsl-function-score-query.html + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class FunctionScoreQueryDescriptor : IQuery where T : class + { + [JsonProperty(PropertyName = "functions")] + internal IEnumerable> _Functions { get; set; } + + [JsonProperty(PropertyName = "query")] + internal BaseQuery _Query { get; set; } + + [JsonProperty(PropertyName = "score_mode")] + [JsonConverter(typeof (StringEnumConverter))] + private FunctionScoreMode? _ScoreMode { get; set; } + + [JsonProperty(PropertyName = "boost_mode")] + [JsonConverter(typeof (StringEnumConverter))] + private FunctionBoostMode? _BoostMode { get; set; } + + [JsonProperty(PropertyName = "random_score")] + private RandomScoreFunction _RandomScore { get; set; } + + [JsonProperty(PropertyName = "script_score")] + private ScriptFilterDescriptor _ScriptScore { get; set; } + + bool IQuery.IsConditionless + { + get + { + return (this._Query == null || this._Query.IsConditionless) && _RandomScore == null && _ScriptScore == null && + (_Functions == null || !_Functions.Any()); + } + } + + public FunctionScoreQueryDescriptor Query(Func, BaseQuery> querySelector) + { + querySelector.ThrowIfNull("querySelector"); + var query = new QueryDescriptor(); + var q = querySelector(query); + + this._Query = q.IsConditionless ? null : q; + return this; + } + + public FunctionScoreQueryDescriptor Functions( + params Func, FunctionScoreFunction>[] functions) + { + var descriptor = new FunctionScoreFunctionsDescriptor(); + + foreach (var f in functions) + { + f(descriptor); + } + + _Functions = descriptor; + + return this; + } + + public FunctionScoreQueryDescriptor ScoreMode(FunctionScoreMode mode) + { + this._ScoreMode = mode; + return this; + } + + public FunctionScoreQueryDescriptor BoostMode(FunctionBoostMode mode) + { + this._BoostMode = mode; + return this; + } + + public FunctionScoreQueryDescriptor RandomScore(int? seed = null) + { + this._RandomScore = new RandomScoreFunction(); + if (seed.HasValue) + { + _RandomScore._Seed = seed.Value; + } + return this; + } + + public FunctionScoreQueryDescriptor ScriptScore(Action scriptSelector) + { + var descriptor = new ScriptFilterDescriptor(); + if (scriptSelector != null) + scriptSelector(descriptor); + + this._ScriptScore = descriptor; + + return this; + } + } + + public enum FunctionScoreMode + { + multiply, + sum, + avg, + first, + max, + min + } + + public enum FunctionBoostMode + { + multiply, + replace, + sum, + avg, + max, + min + } + + public class FunctionScoreFunctionsDescriptor : IEnumerable> where T : class + { + internal List> _Functions { get; set; } + + public FunctionScoreFunctionsDescriptor() + { + this._Functions = new List>(); + } + + public FunctionScoreFunction Gauss(Expression> objectPath, + Action db) + { + var fn = new GaussFunction(objectPath, db); + this._Functions.Add(fn); + return fn; + } + + public FunctionScoreFunction Linear(Expression> objectPath, + Action db) + { + var fn = new LinearFunction(objectPath, db); + this._Functions.Add(fn); + return fn; + } + + public FunctionScoreFunction Exp(Expression> objectPath, + Action db) + { + var fn = new ExpFunction(objectPath, db); + this._Functions.Add(fn); + return fn; + } + + public BoostFactorFunction BoostFactor(double value) + { + var fn = new BoostFactorFunction(value); + this._Functions.Add(fn); + return fn; + } + + public FieldValueFactor FieldValueFactor(Action> db) + { + var fn = new FieldValueFactor(db); + this._Functions.Add(fn); + return fn; + } + + public ScriptScoreFunction ScriptScore(Action scriptSelector) + { + var fn = new ScriptScoreFunction(scriptSelector); + this._Functions.Add(fn); + return fn; + } + + public IEnumerator> GetEnumerator() + { + return _Functions.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _Functions.GetEnumerator(); + } + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class FunctionScoreFunction + { + } + + public class FieldValueFactorDescriptor + { + [JsonProperty("field")] + internal PropertyPathMarker _Field { get; set; } + + [JsonProperty("factor")] + internal double? _Factor { get; set; } + + [JsonProperty("modifier")] + [JsonConverter(typeof (StringEnumConverter))] + internal FieldValueFactorModifier? _Modifier { get; set; } + + public FieldValueFactorDescriptor Field(Expression> field) + { + this._Field = field; + return this; + } + + public FieldValueFactorDescriptor Factor(double factor) + { + this._Factor = factor; + return this; + } + + public FieldValueFactorDescriptor Modifier(FieldValueFactorModifier modifier) + { + this._Modifier = modifier; + return this; + } + } + + public class FunctionScoreDecayFieldDescriptor + { + [JsonProperty(PropertyName = "origin")] + internal string _Origin { get; set; } + + [JsonProperty(PropertyName = "scale")] + internal string _Scale { get; set; } + + [JsonProperty(PropertyName = "offset")] + internal string _Offset { get; set; } + + [JsonProperty(PropertyName = "decay")] + internal double? _Decay { get; set; } + + public FunctionScoreDecayFieldDescriptor Origin(string origin) + { + this._Origin = origin; + return this; + } + + public FunctionScoreDecayFieldDescriptor Scale(string scale) + { + this._Scale = scale; + return this; + } + + public FunctionScoreDecayFieldDescriptor Offset(string offset) + { + this._Offset = offset; + return this; + } + + public FunctionScoreDecayFieldDescriptor Decay(double? decay) + { + this._Decay = decay; + return this; + } + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class FunctionScoreDecayFunction : FunctionScoreFunction + { + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class FunctionScoreFilteredFunction : FunctionScoreFunction where T : class + { + [JsonProperty(PropertyName = "filter")] + internal BaseFilter _Filter { get; set; } + + public FunctionScoreFunction Filter(Func, BaseFilter> filterSelector) + { + filterSelector.ThrowIfNull("filterSelector"); + var filter = new FilterDescriptor(); + var f = filterSelector(filter); + + this._Filter = f; + return this; + } + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class GaussFunction : FunctionScoreDecayFunction + { + [JsonProperty(PropertyName = "gauss")] + [JsonConverter(typeof (DictionaryKeysAreNotPropertyNamesJsonConverter))] + internal IDictionary _GaussDescriptor { get; set; } + + public GaussFunction(Expression> objectPath, + Action descriptorBuilder) + { + _GaussDescriptor = new Dictionary(); + + var descriptor = new FunctionScoreDecayFieldDescriptor(); + descriptorBuilder(descriptor); + _GaussDescriptor[objectPath] = descriptor; + } + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class LinearFunction : FunctionScoreDecayFunction + { + [JsonProperty(PropertyName = "linear")] + [JsonConverter(typeof (DictionaryKeysAreNotPropertyNamesJsonConverter))] + internal IDictionary _LinearDescriptor { get; set; } + + public LinearFunction(Expression> objectPath, + Action descriptorBuilder) + { + _LinearDescriptor = new Dictionary(); + + var descriptor = new FunctionScoreDecayFieldDescriptor(); + descriptorBuilder(descriptor); + _LinearDescriptor[objectPath] = descriptor; + } + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class ExpFunction : FunctionScoreDecayFunction + { + [JsonProperty(PropertyName = "exp")] + [JsonConverter(typeof (DictionaryKeysAreNotPropertyNamesJsonConverter))] + internal IDictionary _ExpDescriptor { get; set; } + + public ExpFunction(Expression> objectPath, Action descriptorBuilder) + { + _ExpDescriptor = new Dictionary(); + + var descriptor = new FunctionScoreDecayFieldDescriptor(); + descriptorBuilder(descriptor); + _ExpDescriptor[objectPath] = descriptor; + } + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class BoostFactorFunction : FunctionScoreFilteredFunction where T : class + { + [JsonProperty(PropertyName = "boost_factor")] + internal double _BoostFactor { get; set; } + + public BoostFactorFunction(double boostFactor) + { + _BoostFactor = boostFactor; + } + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class FieldValueFactor : FunctionScoreFilteredFunction where T : class + { + [JsonProperty(PropertyName = "field_value_factor")] + internal FieldValueFactorDescriptor _FieldValueFactor { get; set; } + + public FieldValueFactor(Action> descriptorBuilder) + { + var descriptor = new FieldValueFactorDescriptor(); + descriptorBuilder(descriptor); + if (descriptor._Field.IsConditionless()) + throw new DslException("Field name not set for field value factor function"); + + this._FieldValueFactor = descriptor; + } + } + + public enum FieldValueFactorModifier + { + none, + log, + log1p, + log2p, + ln, + ln1p, + ln2p, + square, + sqrt, + reciprocal + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class ScriptScoreFunction : FunctionScoreFilteredFunction where T : class + { + [JsonProperty(PropertyName = "script_score")] + internal ScriptFilterDescriptor _ScriptScore { get; set; } + + public ScriptScoreFunction(Action scriptSelector) + { + var descriptor = new ScriptFilterDescriptor(); + if (scriptSelector != null) + scriptSelector(descriptor); + + this._ScriptScore = descriptor; + } + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class RandomScoreFunction + { + [JsonProperty(PropertyName = "seed")] + internal int? _Seed { get; set; } + + public RandomScoreFunction(int seed) + { + _Seed = seed; + } + + public RandomScoreFunction() + { + } + } } \ No newline at end of file diff --git a/src/Tests/Nest.Tests.Unit/Search/Query/Singles/FunctionScoreQueryJson.cs b/src/Tests/Nest.Tests.Unit/Search/Query/Singles/FunctionScoreQueryJson.cs index 78f89a5bf70..cee9dc14d43 100644 --- a/src/Tests/Nest.Tests.Unit/Search/Query/Singles/FunctionScoreQueryJson.cs +++ b/src/Tests/Nest.Tests.Unit/Search/Query/Singles/FunctionScoreQueryJson.cs @@ -1,31 +1,31 @@ -using NUnit.Framework; -using Nest.DSL.Query; -using Nest.Tests.MockData.Domain; - -namespace Nest.Tests.Unit.Search.Query.Singles -{ - [TestFixture] - public class FunctionScoreQueryTests - { - [Test] - public void FunctionScoreQuery() - { - var s = new SearchDescriptor().From(0).Size(10) - .Query(q => q - .FunctionScore(fs => fs - .Query(qq => qq.MatchAll()) - .Functions( - f => f.Gauss(x => x.StartedOn, d => d.Scale("42w")), - f => f.Linear(x => x.FloatValue, d => d.Scale("0.3")), - f => f.Exp(x => x.DoubleValue, d => d.Scale("0.5")), - f => f.BoostFactor(2) - ) - .ScoreMode(FunctionScoreMode.sum) - .BoostMode(FunctionBoostMode.replace) - ) - ).Fields(x => x.Content); - - var json = TestElasticClient.Serialize(s); +using Nest.Tests.MockData.Domain; +using NUnit.Framework; + +namespace Nest.Tests.Unit.Search.Query.Singles +{ + [TestFixture] + public class FunctionScoreQueryTests + { + [Test] + public void FunctionScoreQuery() + { + var s = new SearchDescriptor().From(0).Size(10) + .Query(q => q + .FunctionScore(fs => fs + .Query(qq => qq.MatchAll()) + .Functions( + f => f.Gauss(x => x.StartedOn, d => d.Scale("42w")), + f => f.Linear(x => x.FloatValue, d => d.Scale("0.3")), + f => f.Exp(x => x.DoubleValue, d => d.Scale("0.5")), + f => f.BoostFactor(2.0), + f => f.FieldValueFactor(op => op.Field(ff => ff.DoubleValue).Factor(2.5).Modifier(FieldValueFactorModifier.sqrt)) + ) + .ScoreMode(FunctionScoreMode.sum) + .BoostMode(FunctionBoostMode.replace) + ) + ).Fields(x => x.Content); + + var json = TestElasticClient.Serialize(s); var expected = @"{ from: 0, size: 10, query : { @@ -34,7 +34,8 @@ public void FunctionScoreQuery() {gauss: { startedOn : { scale: '42w'}}}, {linear: { floatValue : { scale: '0.3'}}}, {exp: { doubleValue: { scale: '0.5'}}}, - {boost_factor: 2.0 } + {boost_factor: 2.0 }, + {field_value_factor: { field: 'doubleValue', factor: 2.5, modifier: 'sqrt'}} ], query : { match_all : {} }, score_mode: 'sum', @@ -42,29 +43,30 @@ public void FunctionScoreQuery() } }, fields: [""content""] - }"; - Assert.True(json.JsonEquals(expected), json); - } - - [Test] - public void FunctionScoreQueryConditionless() - { - var s = new SearchDescriptor().From(0).Size(10) - .Query(q => q - .FunctionScore(fs => fs - .Query(qq => qq.Term("", "")) - .Functions( - f => f.Gauss(x => x.StartedOn, d => d.Scale("42w")), - f => f.Linear(x => x.FloatValue, d => d.Scale("0.3")), - f => f.Exp(x => x.DoubleValue, d => d.Scale("0.5")), - f => f.BoostFactor(2) - ) - .ScoreMode(FunctionScoreMode.sum) - .BoostMode(FunctionBoostMode.replace) - ) - ).Fields(x => x.Content); - - var json = TestElasticClient.Serialize(s); + }"; + Assert.True(json.JsonEquals(expected), json); + } + + [Test] + public void FunctionScoreQueryConditionless() + { + var s = new SearchDescriptor().From(0).Size(10) + .Query(q => q + .FunctionScore(fs => fs + .Query(qq => qq.Term("", "")) + .Functions( + f => f.Gauss(x => x.StartedOn, d => d.Scale("42w")), + f => f.Linear(x => x.FloatValue, d => d.Scale("0.3")), + f => f.Exp(x => x.DoubleValue, d => d.Scale("0.5")), + f => f.BoostFactor(2), + f => f.FieldValueFactor(db => db.Field(fa => fa.DoubleValue).Factor(3.4).Modifier(FieldValueFactorModifier.ln)) + ) + .ScoreMode(FunctionScoreMode.sum) + .BoostMode(FunctionBoostMode.replace) + ) + ).Fields(x => x.Content); + + var json = TestElasticClient.Serialize(s); var expected = @"{ from: 0, size: 10, query : { @@ -73,15 +75,29 @@ public void FunctionScoreQueryConditionless() {gauss: { startedOn : { scale: '42w'}}}, {linear: { floatValue : { scale: '0.3'}}}, {exp: { doubleValue: { scale: '0.5'}}}, - {boost_factor: 2.0 } + {boost_factor: 2.0 }, + {field_value_factor: { field: 'doubleValue', factor: 3.4, modifier: 'ln'}} ], score_mode: 'sum', boost_mode: 'replace', } }, fields: [""content""] - }"; - Assert.True(json.JsonEquals(expected), json); - } - } + }"; + Assert.True(json.JsonEquals(expected), json); + } + + [Test] + public void ConditionlessFieldValueFactor() + { + Assert.Throws(() => new SearchDescriptor().From(0).Size(10) + .Query(q => q + .FunctionScore(fs => fs + .Query(qq => qq.Term("", "")) + .Functions( + f => f.FieldValueFactor(db => db.Factor(3.4).Modifier(FieldValueFactorModifier.ln)) + )) + )); + } + } } \ No newline at end of file