Skip to content

Commit 3b6f11b

Browse files
committed
fix #1210 fix #1087 weights on function score query and its functions should be able to pass floats
1 parent e7010bf commit 3b6f11b

File tree

3 files changed

+183
-30
lines changed

3 files changed

+183
-30
lines changed

src/Nest/DSL/Query/FunctionScoreQueryDescriptor.cs

+38-16
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ public interface IFunctionScoreQuery : IQuery
3636
[JsonProperty(PropertyName = "script_score")]
3737
IScriptFilter ScriptScore { get; set; }
3838

39-
[JsonProperty(PropertyName = "weight")]
4039
long? Weight { get; set; }
40+
41+
[JsonProperty(PropertyName = "weight")]
42+
double? WeightAsDouble { get; set; }
4143
}
4244

4345
public class FunctionScoreQuery : PlainQuery, IFunctionScoreQuery
@@ -55,11 +57,20 @@ protected override void WrapInContainer(IQueryContainer container)
5557
public float? MaxBoost { get; set; }
5658
public IRandomScoreFunction RandomScore { get; set; }
5759
public IScriptFilter ScriptScore { get; set; }
58-
public long? Weight { get; set; }
60+
61+
public long? Weight
62+
{
63+
get { return Convert.ToInt64(this.WeightAsDouble ); }
64+
set { this.WeightAsDouble = value; }
65+
}
66+
67+
public double? WeightAsDouble { get; set; }
5968
}
6069

6170
public class FunctionScoreQueryDescriptor<T> : IFunctionScoreQuery where T : class
6271
{
72+
private IFunctionScoreQuery Self { get { return this; }}
73+
6374
IEnumerable<IFunctionScoreFunction> IFunctionScoreQuery.Functions { get; set; }
6475

6576
IQueryContainer IFunctionScoreQuery.Query { get; set; }
@@ -74,16 +85,22 @@ public class FunctionScoreQueryDescriptor<T> : IFunctionScoreQuery where T : cla
7485

7586
IScriptFilter IFunctionScoreQuery.ScriptScore { get; set; }
7687

77-
long? IFunctionScoreQuery.Weight { get; set; }
88+
long? IFunctionScoreQuery.Weight
89+
{
90+
get { return Convert.ToInt64(Self.WeightAsDouble ); }
91+
set { Self.WeightAsDouble = value; }
92+
}
93+
94+
double? IFunctionScoreQuery.WeightAsDouble { get; set; }
7895

7996
bool IQuery.IsConditionless
8097
{
8198
get
8299
{
83-
return (((IFunctionScoreQuery)this).Query == null || ((IFunctionScoreQuery)this).Query.IsConditionless)
84-
&& ((IFunctionScoreQuery)this).RandomScore == null
85-
&& ((IFunctionScoreQuery)this).ScriptScore == null
86-
&& !((IFunctionScoreQuery)this).Functions.HasAny();
100+
return (Self.Query == null || Self.Query.IsConditionless)
101+
&& Self.RandomScore == null
102+
&& Self.ScriptScore == null
103+
&& !Self.Functions.HasAny();
87104
}
88105
}
89106

@@ -92,7 +109,7 @@ public FunctionScoreQueryDescriptor<T> Query(Func<QueryDescriptor<T>, QueryConta
92109
querySelector.ThrowIfNull("querySelector");
93110
var query = new QueryDescriptor<T>();
94111
var q = querySelector(query);
95-
((IFunctionScoreQuery)this).Query = q.IsConditionless ? null :q;
112+
Self.Query = q.IsConditionless ? null :q;
96113
return this;
97114
}
98115

@@ -105,35 +122,35 @@ public FunctionScoreQueryDescriptor<T> Functions(params Func<FunctionScoreFuncti
105122
f(descriptor);
106123
}
107124

108-
((IFunctionScoreQuery)this).Functions = descriptor;
125+
Self.Functions = descriptor;
109126

110127
return this;
111128
}
112129

113130
public FunctionScoreQueryDescriptor<T> ScoreMode(FunctionScoreMode mode)
114131
{
115-
((IFunctionScoreQuery)this).ScoreMode = mode;
132+
Self.ScoreMode = mode;
116133
return this;
117134
}
118135

119136
public FunctionScoreQueryDescriptor<T> BoostMode(FunctionBoostMode mode)
120137
{
121-
((IFunctionScoreQuery)this).BoostMode = mode;
138+
Self.BoostMode = mode;
122139
return this;
123140
}
124141

125142
public FunctionScoreQueryDescriptor<T> MaxBoost(float maxBoost)
126143
{
127-
((IFunctionScoreQuery)this).MaxBoost = maxBoost;
144+
Self.MaxBoost = maxBoost;
128145
return this;
129146
}
130147

131148
public FunctionScoreQueryDescriptor<T> RandomScore(int? seed = null)
132149
{
133-
((IFunctionScoreQuery)this).RandomScore = new RandomScoreFunction();
150+
Self.RandomScore = new RandomScoreFunction();
134151
if (seed.HasValue)
135152
{
136-
((IFunctionScoreQuery)this).RandomScore.Seed = seed.Value;
153+
Self.RandomScore.Seed = seed.Value;
137154
}
138155
return this;
139156
}
@@ -144,14 +161,19 @@ public FunctionScoreQueryDescriptor<T> ScriptScore(Action<ScriptFilterDescriptor
144161
if (scriptSelector != null)
145162
scriptSelector(descriptor);
146163

147-
((IFunctionScoreQuery)this).ScriptScore = descriptor;
164+
Self.ScriptScore = descriptor;
148165

149166
return this;
150167
}
151168

169+
public FunctionScoreQueryDescriptor<T> Weight(double weight)
170+
{
171+
Self.WeightAsDouble = weight;
172+
return this;
173+
}
152174
public FunctionScoreQueryDescriptor<T> Weight(long weight)
153175
{
154-
((IFunctionScoreQuery)this).Weight = weight;
176+
Self.Weight = weight;
155177
return this;
156178
}
157179
}

src/Nest/DSL/Query/Functions/IFunctionScoreFunction.cs

+19-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ public interface IFunctionScoreFunction
1010
{
1111
FilterContainer Filter { get; set; }
1212
long? Weight { get; set; }
13+
14+
/// <summary>
15+
/// This property is added for backwards compatibility reasons and will most likely
16+
/// be renamed to Weight when we release NEST 2.0
17+
/// </summary>
18+
double? WeightAsDouble { get; set; }
1319
}
1420

1521
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
@@ -21,8 +27,14 @@ public class FunctionScoreFunction<T> : IFunctionScoreFunction
2127
[JsonProperty("filter")]
2228
FilterContainer IFunctionScoreFunction.Filter { get; set; }
2329

30+
long? IFunctionScoreFunction.Weight
31+
{
32+
get { return Convert.ToInt64(Self.WeightAsDouble); }
33+
set { Self.WeightAsDouble = value; }
34+
}
35+
2436
[JsonProperty("weight")]
25-
long? IFunctionScoreFunction.Weight { get; set; }
37+
double? IFunctionScoreFunction.WeightAsDouble { get; set; }
2638

2739
public FunctionScoreFunction<T> Filter(Func<FilterDescriptor<T>, FilterContainer> filterSelector)
2840
{
@@ -34,6 +46,12 @@ public FunctionScoreFunction<T> Filter(Func<FilterDescriptor<T>, FilterContainer
3446
return this;
3547
}
3648

49+
public FunctionScoreFunction<T> Weight(double weight)
50+
{
51+
this.Self.WeightAsDouble = weight;
52+
return this;
53+
}
54+
3755
public FunctionScoreFunction<T> Weight(long weight)
3856
{
3957
this.Self.Weight = weight;

src/Tests/Nest.Tests.Unit/Search/Sorting/FunctionScoreTests.cs

+126-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using Nest.Tests.MockData.Domain;
1+
using System.Collections.Generic;
2+
using Nest.Resolvers;
3+
using Nest.Tests.MockData.Domain;
24
using NUnit.Framework;
35

46
namespace Nest.Tests.Unit.Search.Sorting
@@ -105,17 +107,21 @@ public void TestScriptScore()
105107
[Test]
106108
public void TestBoostFactor()
107109
{
108-
var s = new SearchDescriptor<ElasticsearchProject>().Query(
109-
q => q.FunctionScore(
110-
fs => fs.Functions(
111-
f => f.BoostFactor(2)
112-
.Filter(
113-
filter => filter.Term("term1", "termValue")
114-
)
115-
.Weight(5)
110+
var s = new SearchDescriptor<ElasticsearchProject>()
111+
.Query(q => q
112+
.FunctionScore(fs => fs
113+
.Weight(2.0)
114+
.Functions(
115+
f => f
116+
.BoostFactor(2)
117+
.Filter(
118+
filter => filter.Term("term1", "termValue")
119+
)
120+
.Weight(0.5)
121+
)
116122
)
117-
)
118-
);
123+
124+
);
119125
var json = TestElasticClient.Serialize(s);
120126
var expected = @"{
121127
query: {
@@ -128,16 +134,123 @@ public void TestBoostFactor()
128134
""term1"":""termValue""
129135
}
130136
},
131-
weight: 5
137+
weight: 0.5
132138
}
133-
]
139+
],
140+
weight: 2.0
141+
}
142+
}
143+
}";
144+
145+
Assert.True(json.JsonEquals(expected), json);
146+
}
147+
148+
[Test]
149+
public void TestBoostFactor_WrongOverload()
150+
{
151+
var s = new SearchDescriptor<ElasticsearchProject>()
152+
.Query(q => q
153+
.FunctionScore(fs => fs
154+
.Weight(3)
155+
.Functions(
156+
f => f
157+
.BoostFactor(2)
158+
.Filter(
159+
filter => filter.Term("term1", "termValue")
160+
)
161+
.Weight(2)
162+
)
163+
)
164+
165+
);
166+
var json = TestElasticClient.Serialize(s);
167+
var expected = @"{
168+
query: {
169+
function_score: {
170+
functions : [
171+
{
172+
boost_factor: 2.0,
173+
filter:{
174+
term : {
175+
""term1"":""termValue""
176+
}
177+
},
178+
weight: 2.0
179+
}
180+
],
181+
weight: 3.0
134182
}
135183
}
136184
}";
137185

138186
Assert.True(json.JsonEquals(expected), json);
139187
}
140188

189+
[Test]
190+
public void TestBoostFactor_ObjectInitializer()
191+
{
192+
IFunctionScoreFunction boost = new BoostFactorFunction<ElasticsearchProject>(2);
193+
boost.WeightAsDouble = 0.5;
194+
boost.Filter = new TermFilter {Field = Property.Path<ElasticsearchProject>(p => p.Name), Value = "termValue"};
195+
QueryContainer q = new FunctionScoreQuery()
196+
{
197+
WeightAsDouble = 1.0,
198+
Functions = new[] {boost}
199+
200+
};
201+
var json = TestElasticClient.Serialize(q);
202+
var expected = @"{
203+
function_score: {
204+
functions : [
205+
{
206+
boost_factor: 2.0,
207+
filter:{
208+
term : {
209+
""name"":""termValue""
210+
}
211+
},
212+
weight: 0.5
213+
}
214+
],
215+
weight: 1.0
216+
}
217+
}";
218+
219+
Assert.True(json.JsonEquals(expected), json);
220+
}
221+
222+
[Test]
223+
public void TestBoostFactor_ObjectInitializer_WrongProperty()
224+
{
225+
IFunctionScoreFunction boost = new BoostFactorFunction<ElasticsearchProject>(2);
226+
boost.Weight = 1;
227+
boost.Filter = new TermFilter {Field = Property.Path<ElasticsearchProject>(p => p.Name), Value = "termValue"};
228+
QueryContainer q = new FunctionScoreQuery()
229+
{
230+
Weight = 4,
231+
Functions = new[] {boost}
232+
233+
};
234+
var json = TestElasticClient.Serialize(q);
235+
var expected = @"{
236+
function_score: {
237+
functions : [
238+
{
239+
boost_factor: 2.0,
240+
filter:{
241+
term : {
242+
""name"":""termValue""
243+
}
244+
},
245+
weight: 1.0
246+
}
247+
],
248+
weight: 4.0
249+
}
250+
}";
251+
252+
Assert.True(json.JsonEquals(expected), json);
253+
}
141254
[Test]
142255
public void TestDecayFunction()
143256
{

0 commit comments

Comments
 (0)