Fix some minor things in function score parser/builder
- remove default scale weight in builder - make parameters object/double instead of string - do not convert number to string and back again, parse double instead - remove javadoc reference to test classes - Set parameters in constructor instead of in method
This commit is contained in:
parent
592e637293
commit
ebbd00acc2
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.elasticsearch.index.query.functionscore;
|
||||
|
||||
|
||||
import org.elasticsearch.ElasticSearchIllegalStateException;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
|
@ -30,45 +29,37 @@ public abstract class DecayFunctionBuilder implements ScoreFunctionBuilder {
|
|||
protected static final String REFERNECE = "reference";
|
||||
protected static final String SCALE = "scale";
|
||||
protected static final String SCALE_WEIGHT = "scale_weight";
|
||||
protected static final String SCALE_DEFAULT = "0.5";
|
||||
|
||||
private String fieldName;
|
||||
private String reference;
|
||||
private String scale;
|
||||
private String scaleWeight;
|
||||
|
||||
public void setParameters(String fieldName, String reference, String scale, String scaleWeight) {
|
||||
if(this.fieldName != null ) {
|
||||
throw new ElasticSearchIllegalStateException("Can not set parameters of decay function more than once.");
|
||||
}
|
||||
private String fieldName;
|
||||
private Object reference;
|
||||
private Object scale;
|
||||
private double scaleWeight = -1;
|
||||
|
||||
public DecayFunctionBuilder(String fieldName, Object reference, Object scale) {
|
||||
this.fieldName = fieldName;
|
||||
this.reference = reference;
|
||||
this.scale = scale;
|
||||
}
|
||||
public DecayFunctionBuilder setScaleWeight(double scaleWeight) {
|
||||
if(scaleWeight <=0 || scaleWeight >= 1.0) {
|
||||
throw new ElasticSearchIllegalStateException("scale weight parameter must be in range 0..1!");
|
||||
}
|
||||
this.scaleWeight = scaleWeight;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setParameters(String fieldName, String reference, String scale) {
|
||||
setParameters(fieldName, reference, scale, SCALE_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(getName());
|
||||
builder.startObject(fieldName);
|
||||
builder.field(REFERNECE, reference);
|
||||
builder.field(SCALE, scale);
|
||||
builder.startObject(fieldName);
|
||||
builder.field(REFERNECE, reference);
|
||||
builder.field(SCALE, scale);
|
||||
if (scaleWeight > 0) {
|
||||
builder.field(SCALE_WEIGHT, scaleWeight);
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public void addGeoParams(String fieldName, double lat, double lon, String scale) {
|
||||
addGeoParams(fieldName, lat, lon, scale, SCALE_DEFAULT);
|
||||
}
|
||||
|
||||
public void addGeoParams(String fieldName, double lat, double lon, String scale, String scaleWeight) {
|
||||
String geoLoc = Double.toString(lat) + ", " + Double.toString(lon);
|
||||
setParameters(fieldName, geoLoc, scale, scaleWeight);
|
||||
}
|
||||
}
|
|
@ -84,12 +84,7 @@ import java.io.IOException;
|
|||
* See {@link GaussDecayFunctionBuilder} and {@link GaussDecayFunctionParser}
|
||||
* for an example. The parser furthermore needs to be registered in the
|
||||
* {@link org.elasticsearch.index.query.functionscore.FunctionScoreModule
|
||||
* FunctionScoreModule}. See
|
||||
* {@link org.elasticsearch.test.integration.search.functionscore.CustomDistanceScorePlugin
|
||||
* CustomDistanceScorePlugin} and
|
||||
* {@link org.elasticsearch.test.integration.search.functionscore.CustomDistanceScorePlugin
|
||||
* DistanceScorePluginTest DistanceScorePluginTest} for an example on how to
|
||||
* write your own function and plugin.
|
||||
* FunctionScoreModule}.
|
||||
*
|
||||
* **/
|
||||
|
||||
|
@ -165,28 +160,30 @@ public abstract class DecayFunctionParser implements ScoreFunctionParser {
|
|||
NumberFieldMapper<?> mapper) throws IOException {
|
||||
XContentParser.Token token;
|
||||
String parameterName = null;
|
||||
String scaleString = null;
|
||||
String referenceString = null;
|
||||
double scale = 0;
|
||||
double reference = 0;
|
||||
double scaleWeight = 0.5;
|
||||
boolean scaleFound = false;
|
||||
boolean refFound = false;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
parameterName = parser.currentName();
|
||||
} else if (parameterName.equals(DecayFunctionBuilder.SCALE)) {
|
||||
scaleString = parser.text();
|
||||
scale = parser.doubleValue();
|
||||
scaleFound = true;
|
||||
} else if (parameterName.equals(DecayFunctionBuilder.SCALE_WEIGHT)) {
|
||||
scaleWeight = parser.doubleValue();
|
||||
} else if (parameterName.equals(DecayFunctionBuilder.REFERNECE)) {
|
||||
referenceString = parser.text();
|
||||
reference = parser.doubleValue();
|
||||
refFound = true;
|
||||
} else {
|
||||
throw new ElasticSearchParseException("Parameter " + parameterName + " not supported!");
|
||||
}
|
||||
}
|
||||
if (scaleString == null || referenceString == null) {
|
||||
if (!scaleFound || !refFound) {
|
||||
throw new ElasticSearchParseException("Both " + DecayFunctionBuilder.SCALE + "and " + DecayFunctionBuilder.REFERNECE
|
||||
+ " must be set for numeric fields.");
|
||||
}
|
||||
double reference = mapper.value(referenceString).doubleValue();
|
||||
double scale = mapper.value(scaleString).doubleValue();
|
||||
IndexNumericFieldData<?> numericFieldData = parseContext.fieldData().getForField(mapper);
|
||||
return new NumericFieldDataScoreFunction(reference, scale, scaleWeight, getDecayFunction(), numericFieldData);
|
||||
}
|
||||
|
@ -375,7 +372,7 @@ public abstract class DecayFunctionParser implements ScoreFunctionParser {
|
|||
@Override
|
||||
public Explanation explainScore(int docId, Explanation subQueryExpl) {
|
||||
ComplexExplanation ce = new ComplexExplanation();
|
||||
ce.setValue((float)score(docId, subQueryExpl.getValue()));
|
||||
ce.setValue((float) score(docId, subQueryExpl.getValue()));
|
||||
ce.setMatch(true);
|
||||
ce.setDescription("subQueryScore * Function for field " + getFieldName() + ":");
|
||||
ce.addDetail(func.explainFunction(getDistanceString(docId), distance(docId), scale));
|
||||
|
@ -385,7 +382,7 @@ public abstract class DecayFunctionParser implements ScoreFunctionParser {
|
|||
@Override
|
||||
public Explanation explainFactor(int docId) {
|
||||
ComplexExplanation ce = new ComplexExplanation();
|
||||
ce.setValue((float)factor(docId));
|
||||
ce.setValue((float) factor(docId));
|
||||
ce.setMatch(true);
|
||||
ce.setDescription("subQueryScore * Function for field " + getFieldName() + ":");
|
||||
ce.addDetail(func.explainFunction(getDistanceString(docId), distance(docId), scale));
|
||||
|
|
|
@ -24,6 +24,10 @@ import org.elasticsearch.index.query.functionscore.DecayFunctionBuilder;
|
|||
|
||||
public class ExponentialDecayFunctionBuilder extends DecayFunctionBuilder {
|
||||
|
||||
public ExponentialDecayFunctionBuilder(String fieldName, Object reference, Object scale) {
|
||||
super(fieldName, reference, scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return ExponentialDecayFunctionParser.NAMES[0];
|
||||
|
|
|
@ -24,6 +24,10 @@ import org.elasticsearch.index.query.functionscore.DecayFunctionBuilder;
|
|||
|
||||
public class GaussDecayFunctionBuilder extends DecayFunctionBuilder {
|
||||
|
||||
public GaussDecayFunctionBuilder(String fieldName, Object reference, Object scale) {
|
||||
super(fieldName, reference, scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return GaussDecayFunctionParser.NAMES[0];
|
||||
|
|
|
@ -23,6 +23,10 @@ import org.elasticsearch.index.query.functionscore.DecayFunctionBuilder;
|
|||
|
||||
public class LinearDecayFunctionBuilder extends DecayFunctionBuilder {
|
||||
|
||||
public LinearDecayFunctionBuilder(String fieldName, Object reference, Object scale) {
|
||||
super(fieldName, reference, scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return LinearDecayFunctionParser.NAMES[0];
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.test.integration.search.functionscore;
|
||||
|
||||
import org.elasticsearch.ElasticSearchIllegalStateException;
|
||||
import org.elasticsearch.action.ActionFuture;
|
||||
import org.elasticsearch.action.index.IndexRequestBuilder;
|
||||
import org.elasticsearch.action.search.SearchPhaseExecutionException;
|
||||
|
@ -86,8 +87,10 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
|||
refresh();
|
||||
|
||||
// Test Gauss
|
||||
DecayFunctionBuilder fb = new GaussDecayFunctionBuilder();
|
||||
fb.addGeoParams("loc", 11, 20, "1000km");
|
||||
List<Float> lonlat = new ArrayList<Float>();
|
||||
lonlat.add(new Float(20));
|
||||
lonlat.add(new Float(11));
|
||||
DecayFunctionBuilder fb = new GaussDecayFunctionBuilder("loc", lonlat, "1000km");
|
||||
|
||||
ActionFuture<SearchResponse> response = client().search(
|
||||
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||
|
@ -106,8 +109,7 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
|||
assertThat(sh.getAt(0).getId(), equalTo("1"));
|
||||
assertThat(sh.getAt(1).getId(), equalTo("2"));
|
||||
// Test Exp
|
||||
fb = new ExponentialDecayFunctionBuilder();
|
||||
fb.addGeoParams("loc", 11, 20, "1000km");
|
||||
fb = new ExponentialDecayFunctionBuilder("loc", lonlat, "1000km");
|
||||
|
||||
response = client().search(
|
||||
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||
|
@ -126,8 +128,7 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
|||
assertThat(sh.getAt(0).getId(), equalTo("1"));
|
||||
assertThat(sh.getAt(1).getId(), equalTo("2"));
|
||||
// Test Lin
|
||||
fb = new LinearDecayFunctionBuilder();
|
||||
fb.addGeoParams("loc", 11, 20, "1000km");
|
||||
fb = new LinearDecayFunctionBuilder("loc", lonlat, "1000km");
|
||||
|
||||
response = client().search(
|
||||
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||
|
@ -160,8 +161,7 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
|||
.source(jsonBuilder().startObject().field("test", "value").field("num1", "2013-05-28").endObject())).actionGet();
|
||||
refresh();
|
||||
|
||||
DecayFunctionBuilder gfb = new GaussDecayFunctionBuilder();
|
||||
gfb.setParameters("num1", "2013-05-28", "-1d");
|
||||
DecayFunctionBuilder gfb = new GaussDecayFunctionBuilder("num1", "2013-05-28", "-1d");
|
||||
|
||||
ActionFuture<SearchResponse> response = client().search(
|
||||
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||
|
@ -176,32 +176,10 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
|||
|
||||
}
|
||||
|
||||
@Test(expected = SearchPhaseExecutionException.class)
|
||||
@Test(expected = ElasticSearchIllegalStateException.class)
|
||||
public void testExceptionThrownIfScaleRefNotBetween0And1() throws Exception {
|
||||
|
||||
createIndexMapped("test", "type1", "test", "string", "num1", "date");
|
||||
ensureYellow();
|
||||
client().index(
|
||||
indexRequest("test").type("type1").id("1")
|
||||
.source(jsonBuilder().startObject().field("test", "value").field("num1", "2013-05-27").endObject())).actionGet();
|
||||
client().index(
|
||||
indexRequest("test").type("type1").id("2")
|
||||
.source(jsonBuilder().startObject().field("test", "value").field("num1", "2013-05-28").endObject())).actionGet();
|
||||
refresh();
|
||||
|
||||
DecayFunctionBuilder gfb = new GaussDecayFunctionBuilder();
|
||||
gfb.setParameters("num1", "2013-05-28", "1d", "-1");
|
||||
|
||||
ActionFuture<SearchResponse> response = client().search(
|
||||
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||
searchSource().explain(true).query(functionScoreQuery(termQuery("test", "value")).add(gfb))));
|
||||
|
||||
SearchResponse sr = response.actionGet();
|
||||
ElasticsearchAssertions.assertNoFailures(sr);
|
||||
SearchHits sh = sr.getHits();
|
||||
assertThat(sh.hits().length, equalTo(2));
|
||||
assertThat(sh.getAt(0).getId(), equalTo("2"));
|
||||
assertThat(sh.getAt(1).getId(), equalTo("1"));
|
||||
DecayFunctionBuilder gfb = new GaussDecayFunctionBuilder("num1", "2013-05-28", "1d").setScaleWeight(100);
|
||||
|
||||
}
|
||||
|
||||
|
@ -231,10 +209,8 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
|||
|
||||
refresh();
|
||||
|
||||
DecayFunctionBuilder gfb1 = new LinearDecayFunctionBuilder();
|
||||
gfb1.setParameters("num1", "2013-05-28", "+3d");
|
||||
DecayFunctionBuilder gfb2 = new LinearDecayFunctionBuilder();
|
||||
gfb2.setParameters("num2", "0.0", "1");
|
||||
DecayFunctionBuilder gfb1 = new LinearDecayFunctionBuilder("num1", "2013-05-28", "+3d");
|
||||
DecayFunctionBuilder gfb2 = new LinearDecayFunctionBuilder("num2", "0.0", "1");
|
||||
|
||||
ActionFuture<SearchResponse> response = client().search(
|
||||
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||
|
@ -282,13 +258,13 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
|||
|
||||
indexRandom("test", false, builders);
|
||||
refresh();
|
||||
|
||||
DecayFunctionBuilder gfb1 = new LinearDecayFunctionBuilder();
|
||||
DecayFunctionBuilder gfb2 = new LinearDecayFunctionBuilder();
|
||||
DecayFunctionBuilder gfb3 = new LinearDecayFunctionBuilder();
|
||||
gfb1.setParameters("date", "2013-05-30", "+15d");
|
||||
gfb2.addGeoParams("geo", 110, 100, "1000km");
|
||||
gfb3.setParameters("num", Integer.toString(numDocs), Integer.toString(numDocs / 2));
|
||||
|
||||
List<Float> lonlat = new ArrayList<Float>();
|
||||
lonlat.add(new Float(100));
|
||||
lonlat.add(new Float(110));
|
||||
DecayFunctionBuilder gfb1 = new LinearDecayFunctionBuilder("date", "2013-05-30", "+15d");
|
||||
DecayFunctionBuilder gfb2 = new LinearDecayFunctionBuilder("geo", lonlat, "1000km");
|
||||
DecayFunctionBuilder gfb3 = new LinearDecayFunctionBuilder("num", Integer.toString(numDocs), Integer.toString(numDocs / 2));
|
||||
|
||||
ActionFuture<SearchResponse> response = client().search(
|
||||
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||
|
@ -324,8 +300,10 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
|||
jsonBuilder().startObject().field("test", "value").startObject("geo").field("lat", 1).field("lon", 2).endObject()
|
||||
.endObject())).actionGet();
|
||||
refresh();
|
||||
DecayFunctionBuilder gfb2 = new LinearDecayFunctionBuilder();
|
||||
gfb2.addGeoParams("type1.geo", 110, 100, "1000km");
|
||||
List<Float> lonlat = new ArrayList<Float>();
|
||||
lonlat.add(new Float(100));
|
||||
lonlat.add(new Float(110));
|
||||
DecayFunctionBuilder gfb2 = new LinearDecayFunctionBuilder("type1.geo", lonlat, "1000km");
|
||||
ActionFuture<SearchResponse> response = client().search(
|
||||
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||
searchSource()
|
||||
|
@ -345,9 +323,8 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
|||
indexRequest("test").type("type").source(
|
||||
jsonBuilder().startObject().field("test", "value").field("num", Integer.toString(1)).endObject())).actionGet();
|
||||
refresh();
|
||||
DecayFunctionBuilder lfb = new LinearDecayFunctionBuilder();
|
||||
//so, we indexed a string field, but now we try to score a num field
|
||||
lfb.setParameters("num", Integer.toString(1), Integer.toString(1 / 2));
|
||||
DecayFunctionBuilder lfb = new LinearDecayFunctionBuilder("num", Integer.toString(1), Integer.toString(1 / 2));
|
||||
// so, we indexed a string field, but now we try to score a num field
|
||||
ActionFuture<SearchResponse> response = client()
|
||||
.search(searchRequest()
|
||||
.searchType(SearchType.QUERY_THEN_FETCH)
|
||||
|
|
|
@ -83,8 +83,7 @@ public class FunctionScorePluginTests extends AbstractNodesTests {
|
|||
.source(jsonBuilder().startObject().field("test", "value").field("num1", "2013-05-27").endObject())).actionGet();
|
||||
|
||||
client.admin().indices().prepareRefresh().execute().actionGet();
|
||||
DecayFunctionBuilder gfb = new CustomDistanceScoreBuilder();
|
||||
gfb.setParameters("num1", "2013-05-28", "+1d");
|
||||
DecayFunctionBuilder gfb = new CustomDistanceScoreBuilder("num1", "2013-05-28", "+1d");
|
||||
|
||||
ActionFuture<SearchResponse> response = client.search(searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||
searchSource().explain(false).query(functionScoreQuery(termQuery("test", "value")).add(gfb))));
|
||||
|
@ -160,6 +159,10 @@ public class FunctionScorePluginTests extends AbstractNodesTests {
|
|||
public class CustomDistanceScoreBuilder extends DecayFunctionBuilder {
|
||||
|
||||
|
||||
public CustomDistanceScoreBuilder(String fieldName, Object reference, Object scale) {
|
||||
super(fieldName, reference, scale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return CustomDistanceScoreParser.NAMES[0];
|
||||
|
|
Loading…
Reference in New Issue