FunctionScore: RandomScoreFunction now accepts long, as well a strings.
closes #8267 closes #8311
This commit is contained in:
parent
f1f50ac423
commit
8aff3b6273
|
@ -80,6 +80,14 @@ public class ScoreFunctionBuilders {
|
|||
public static RandomScoreFunctionBuilder randomFunction(int seed) {
|
||||
return (new RandomScoreFunctionBuilder()).seed(seed);
|
||||
}
|
||||
|
||||
public static RandomScoreFunctionBuilder randomFunction(long seed) {
|
||||
return (new RandomScoreFunctionBuilder()).seed(seed);
|
||||
}
|
||||
|
||||
public static RandomScoreFunctionBuilder randomFunction(String seed) {
|
||||
return (new RandomScoreFunctionBuilder()).seed(seed);
|
||||
}
|
||||
|
||||
public static WeightBuilder weightFactorFunction(float weight) {
|
||||
return (WeightBuilder)(new WeightBuilder().setWeight(weight));
|
||||
|
|
|
@ -28,7 +28,7 @@ import java.io.IOException;
|
|||
*/
|
||||
public class RandomScoreFunctionBuilder extends ScoreFunctionBuilder {
|
||||
|
||||
private Integer seed = null;
|
||||
private Object seed = null;
|
||||
|
||||
public RandomScoreFunctionBuilder() {
|
||||
}
|
||||
|
@ -49,11 +49,31 @@ public class RandomScoreFunctionBuilder extends ScoreFunctionBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* seed variant taking a long value.
|
||||
* @see {@link #seed(int)}
|
||||
*/
|
||||
public RandomScoreFunctionBuilder seed(long seed) {
|
||||
this.seed = seed;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* seed variant taking a String value.
|
||||
* @see {@link #seed(int)}
|
||||
*/
|
||||
public RandomScoreFunctionBuilder seed(String seed) {
|
||||
this.seed = seed;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(getName());
|
||||
if (seed != null) {
|
||||
builder.field("seed", seed.intValue());
|
||||
if (seed instanceof Number) {
|
||||
builder.field("seed", ((Number)seed).longValue());
|
||||
} else if (seed != null) {
|
||||
builder.field("seed", seed.toString());
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
package org.elasticsearch.index.query.functionscore.random;
|
||||
|
||||
import com.google.common.primitives.Longs;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.lucene.search.function.RandomScoreFunction;
|
||||
import org.elasticsearch.common.lucene.search.function.ScoreFunction;
|
||||
|
@ -59,7 +60,19 @@ public class RandomScoreFunctionParser implements ScoreFunctionParser {
|
|||
currentFieldName = parser.currentName();
|
||||
} else if (token.isValue()) {
|
||||
if ("seed".equals(currentFieldName)) {
|
||||
seed = parser.intValue();
|
||||
if (token == XContentParser.Token.VALUE_NUMBER) {
|
||||
if (parser.numberType() == XContentParser.NumberType.INT) {
|
||||
seed = parser.intValue();
|
||||
} else if (parser.numberType() == XContentParser.NumberType.LONG) {
|
||||
seed = Longs.hashCode(parser.longValue());
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "random_score seed must be an int, long or string, not '" + token.toString() + "'");
|
||||
}
|
||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||
seed = parser.text().hashCode();
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), "random_score seed must be an int/long or string, not '" + token.toString() + "'");
|
||||
}
|
||||
} else {
|
||||
throw new QueryParsingException(parseContext.index(), NAMES[0] + " query does not support [" + currentFieldName + "]");
|
||||
}
|
||||
|
@ -73,7 +86,7 @@ public class RandomScoreFunctionParser implements ScoreFunctionParser {
|
|||
}
|
||||
|
||||
if (seed == -1) {
|
||||
seed = (int)parseContext.nowInMillis();
|
||||
seed = Longs.hashCode(parseContext.nowInMillis());
|
||||
}
|
||||
final ShardId shardId = SearchContext.current().indexShard().shardId();
|
||||
final int salt = (shardId.index().name().hashCode() << 10) | shardId.id();
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.elasticsearch.search.SearchHit;
|
|||
import org.elasticsearch.test.ElasticsearchIntegrationTest;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
@ -41,7 +40,6 @@ import static org.hamcrest.Matchers.*;
|
|||
|
||||
public class RandomScoreFunctionTests extends ElasticsearchIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void testConsistentHitsWithSameSeed() throws Exception {
|
||||
createIndex("test");
|
||||
ensureGreen(); // make sure we are done otherwise preference could change?
|
||||
|
@ -103,7 +101,6 @@ public class RandomScoreFunctionTests extends ElasticsearchIntegrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScoreAccessWithinScript() throws Exception {
|
||||
assertAcked(prepareCreate("test")
|
||||
.addMapping("type", "body", "type=string", "index", "type=" + randomFrom(new String[]{"short", "float", "long", "integer", "double"})));
|
||||
|
@ -170,7 +167,6 @@ public class RandomScoreFunctionTests extends ElasticsearchIntegrationTest {
|
|||
assertThat(firstHit.getScore(), greaterThan(1f));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSeedReportedInExplain() throws Exception {
|
||||
createIndex("test");
|
||||
ensureGreen();
|
||||
|
@ -201,7 +197,6 @@ public class RandomScoreFunctionTests extends ElasticsearchIntegrationTest {
|
|||
assertEquals(0, resp.getHits().totalHits());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScoreRange() throws Exception {
|
||||
// all random scores should be in range [0.0, 1.0]
|
||||
createIndex("test");
|
||||
|
@ -227,8 +222,32 @@ public class RandomScoreFunctionTests extends ElasticsearchIntegrationTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testSeeds() throws Exception {
|
||||
createIndex("test");
|
||||
ensureGreen();
|
||||
final int docCount = randomIntBetween(100, 200);
|
||||
for (int i = 0; i < docCount; i++) {
|
||||
index("test", "type", "" + i, jsonBuilder().startObject().endObject());
|
||||
}
|
||||
flushAndRefresh();
|
||||
|
||||
assertNoFailures(client().prepareSearch()
|
||||
.setSize(docCount) // get all docs otherwise we are prone to tie-breaking
|
||||
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(randomInt())))
|
||||
.execute().actionGet());
|
||||
|
||||
assertNoFailures(client().prepareSearch()
|
||||
.setSize(docCount) // get all docs otherwise we are prone to tie-breaking
|
||||
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(randomLong())))
|
||||
.execute().actionGet());
|
||||
|
||||
assertNoFailures(client().prepareSearch()
|
||||
.setSize(docCount) // get all docs otherwise we are prone to tie-breaking
|
||||
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(randomRealisticUnicodeOfLengthBetween(10, 20))))
|
||||
.execute().actionGet());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void checkDistribution() throws Exception {
|
||||
int count = 10000;
|
||||
|
|
Loading…
Reference in New Issue