FunctionScore: Fixed RandomScoreFunction to guard against _uid field not existing.

Also added a test case to check the random score works with queries on
an empty index.
This commit is contained in:
Ryan Ernst 2014-08-27 17:00:04 -07:00
parent 59da079bae
commit eb22d9ec24
3 changed files with 29 additions and 8 deletions

View File

@ -35,6 +35,14 @@ public class RandomScoreFunction extends ScoreFunction {
private final IndexFieldData<?> uidFieldData;
private SortedBinaryDocValues uidByteData;
/**
* Default constructor. Only useful for constructing as a placeholder, but should not be used for actual scoring.
*/
public RandomScoreFunction() {
super(CombineFunction.MULT);
uidFieldData = null;
}
/**
* Creates a RandomScoreFunction.
*

View File

@ -66,15 +66,18 @@ public class RandomScoreFunctionParser implements ScoreFunctionParser {
}
}
final FieldMapper<?> mapper = SearchContext.current().mapperService().smartNameFieldMapper("_uid");
if (mapper == null) {
// mapper could be null if we are on a shard with no docs yet, so this won't actually be used
return new RandomScoreFunction();
}
if (seed == -1) {
seed = (int)parseContext.nowInMillis();
}
ShardId shardId = SearchContext.current().indexShard().shardId();
int salt = (shardId.index().name().hashCode() << 10) | shardId.id();
final FieldMapper<?> mapper = SearchContext.current().mapperService().smartNameFieldMapper("_uid");
IndexFieldData<?> uidFieldData = SearchContext.current().fieldData().getForField(mapper);
final ShardId shardId = SearchContext.current().indexShard().shardId();
final int salt = (shardId.index().name().hashCode() << 10) | shardId.id();
final IndexFieldData<?> uidFieldData = SearchContext.current().fieldData().getForField(mapper);
return new RandomScoreFunction(seed, salt, uidFieldData);
}

View File

@ -18,7 +18,6 @@
*/
package org.elasticsearch.search.functionscore;
import org.apache.lucene.search.Explanation;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.functionscore.random.RandomScoreFunctionBuilder;
import org.elasticsearch.search.SearchHit;
@ -37,7 +36,7 @@ import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.arrayContaining;
public class RandomScoreFunctionTests extends ElasticsearchIntegrationTest {
@ -179,6 +178,17 @@ public class RandomScoreFunctionTests extends ElasticsearchIntegrationTest {
assertThat(firstHit.explanation().toString(), containsString("" + seed));
}
public void testNoDocs() throws Exception {
createIndex("test");
ensureGreen();
SearchResponse resp = client().prepareSearch("test")
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(1234)))
.get();
assertNoFailures(resp);
assertEquals(0, resp.getHits().totalHits());
}
@Test
public void testScoreRange() throws Exception {
// all random scores should be in range [0.0, 1.0]