tests: add testfunc to ensure weighting occurs

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1242617 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2012-02-10 00:22:01 +00:00
parent d06fe21f88
commit 6c4139a62b
3 changed files with 64 additions and 7 deletions

View File

@ -28,6 +28,7 @@ import org.apache.lucene.queries.function.valuesource.*;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.spell.JaroWinklerDistance;
import org.apache.lucene.search.spell.LevensteinDistance;
@ -38,10 +39,12 @@ import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.UnicodeUtil;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.request.SolrRequestInfo;
import org.apache.solr.schema.*;
import org.apache.solr.search.function.distance.*;
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
import org.omg.PortableInterceptor.RequestInfo;
import java.io.IOException;
import java.util.*;
@ -86,6 +89,13 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
}
static {
addParser("testfunc", new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws ParseException {
final ValueSource source = fp.parseValueSource();
return new TestValueSource(source);
}
});
addParser("ord", new ValueSourceParser() {
@Override
public ValueSource parse(FunctionQParser fp) throws ParseException {
@ -1205,3 +1215,46 @@ class BoolConstValueSource extends ConstNumberSource {
return constant;
}
}
class TestValueSource extends ValueSource {
ValueSource source;
public TestValueSource(ValueSource source) {
this.source = source;
}
@Override
public FunctionValues getValues(Map context, AtomicReaderContext readerContext) throws IOException {
if (context.get(this) == null) {
SolrRequestInfo requestInfo = SolrRequestInfo.getRequestInfo();
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "testfunc: unweighted value source detected. delegate="+source + " request=" + (requestInfo==null ? "null" : requestInfo.getReq()));
}
return source.getValues(context, readerContext);
}
@Override
public boolean equals(Object o) {
return o instanceof TestValueSource && source.equals(((TestValueSource)o).source);
}
@Override
public int hashCode() {
return source.hashCode() + TestValueSource.class.hashCode();
}
@Override
public String description() {
return "testfunc(" + source.description() + ')';
}
@Override
public void createWeight(Map context, IndexSearcher searcher) throws IOException {
context.put(this, this);
}
@Override
public SortField getSortField(boolean reverse) throws IOException {
return super.getSortField(reverse);
}
}

View File

@ -111,7 +111,7 @@ public class TestDistributedSearch extends BaseDistributedSearchTestCase {
// these queries should be exactly ordered and scores should exactly match
query("q","*:*", "sort",i1+" desc");
query("q","*:*", "sort","{!func}add("+i1+",5)"+" desc");
query("q","*:*", "sort","{!func}testfunc(add("+i1+",5))"+" desc");
query("q","*:*", "sort",i1+" asc");
query("q","*:*", "sort",i1+" desc", "fl","*,score");
query("q","*:*", "sort","n_tl1 asc", "fl","score"); // test legacy behavior - "score"=="*,score"

View File

@ -678,6 +678,10 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
assertU(adoc("id", "2" , "foo_ti","10", "foo_tl","11"));
assertU(commit());
// test weighting of functions
assertJQ(req("q", "id:1", "fl", "a:testfunc(1)")
, "/response/docs/[0]=={'a':1}");
// true and false functions and constants
assertJQ(req("q", "id:1", "fl", "t:true(),f:false(),tt:{!func}true,ff:{!func}false")
, "/response/docs/[0]=={'t':true,'f':false,'tt':true,'ff':false}");
@ -687,22 +691,22 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
, "/response/docs/[0]=={'t':true,'f':false}");
// test if()
assertJQ(req("q", "id:1", "fl", "a1:if(true,'A','B')", "fl","b1:if(false,'A','B')")
assertJQ(req("q", "id:1", "fl", "a1:if(true,'A','B')", "fl","b1:if(false,'A',testfunc('B'))")
, "/response/docs/[0]=={'a1':'A', 'b1':'B'}");
// test boolean operators
assertJQ(req("q", "id:1", "fl", "t1:and(true,true)", "fl","f1:and(true,false)", "fl","f2:and(false,true)", "fl","f3:and(false,false)")
assertJQ(req("q", "id:1", "fl", "t1:and(testfunc(true),true)", "fl","f1:and(true,false)", "fl","f2:and(false,true)", "fl","f3:and(false,false)")
, "/response/docs/[0]=={'t1':true, 'f1':false, 'f2':false, 'f3':false}");
assertJQ(req("q", "id:1", "fl", "t1:or(true,true)", "fl","t2:or(true,false)", "fl","t3:or(false,true)", "fl","f1:or(false,false)")
assertJQ(req("q", "id:1", "fl", "t1:or(testfunc(true),true)", "fl","t2:or(true,false)", "fl","t3:or(false,true)", "fl","f1:or(false,false)")
, "/response/docs/[0]=={'t1':true, 't2':true, 't3':true, 'f1':false}");
assertJQ(req("q", "id:1", "fl", "f1:xor(true,true)", "fl","t1:xor(true,false)", "fl","t2:xor(false,true)", "fl","f2:xor(false,false)")
assertJQ(req("q", "id:1", "fl", "f1:xor(testfunc(true),true)", "fl","t1:xor(true,false)", "fl","t2:xor(false,true)", "fl","f2:xor(false,false)")
, "/response/docs/[0]=={'t1':true, 't2':true, 'f1':false, 'f2':false}");
assertJQ(req("q", "id:1", "fl", "t:not(false),f:not(true)")
assertJQ(req("q", "id:1", "fl", "t:not(testfunc(false)),f:not(true)")
, "/response/docs/[0]=={'t':true, 'f':false}");
// def(), the default function that returns the first value that exists
assertJQ(req("q", "id:1", "fl", "x:def(id,123.0), y:def(foo_f,234.0)")
assertJQ(req("q", "id:1", "fl", "x:def(id,testfunc(123.0)), y:def(foo_f,234.0)")
, "/response/docs/[0]=={'x':1.0, 'y':234.0}");
assertJQ(req("q", "id:1", "fl", "x:def(foo_s,'Q'), y:def(missing_s,'W')")
, "/response/docs/[0]=={'x':'A', 'y':'W'}");