aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2017-02-01 00:49:28 +0100
committerHenning Baldersheim <balder@yahoo-inc.com>2017-02-01 00:49:28 +0100
commit1bda2e5d4913415ca9e4dcec49a70352f7bf9373 (patch)
tree6c5ffaf4b22a77d5dbaa16f0a0c5dbabbf0f3593 /container-search/src
parent09891fa60e5da3d2713020018ca242c67cde9f9e (diff)
Add querytime control overer ranking.matching.xxxx
Diffstat (limited to 'container-search/src')
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/Ranking.java11
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java19
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java123
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/ranking/SoftTimeout.java (renamed from container-search/src/main/java/com/yahoo/search/query/SoftTimeout.java)4
-rw-r--r--container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java54
5 files changed, 207 insertions, 4 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/query/Ranking.java b/container-search/src/main/java/com/yahoo/search/query/Ranking.java
index addd759cd29..17ec32b200a 100644
--- a/container-search/src/main/java/com/yahoo/search/query/Ranking.java
+++ b/container-search/src/main/java/com/yahoo/search/query/Ranking.java
@@ -8,8 +8,10 @@ import com.yahoo.search.Query;
import com.yahoo.search.query.profile.types.FieldDescription;
import com.yahoo.search.query.profile.types.QueryProfileType;
import com.yahoo.search.query.ranking.MatchPhase;
+import com.yahoo.search.query.ranking.Matching;
import com.yahoo.search.query.ranking.RankFeatures;
import com.yahoo.search.query.ranking.RankProperties;
+import com.yahoo.search.query.ranking.SoftTimeout;
import com.yahoo.search.result.ErrorMessage;
/**
@@ -38,6 +40,7 @@ public class Ranking implements Cloneable {
public static final String MATCH_PHASE = "matchPhase";
public static final String DIVERSITY = "diversity";
public static final String SOFTTIMEOUT = "softtimeout";
+ public static final String MATCHING = "matching";
public static final String FEATURES = "features";
public static final String PROPERTIES = "properties";
@@ -83,6 +86,8 @@ public class Ranking implements Cloneable {
private MatchPhase matchPhase = new MatchPhase();
+ private Matching matching = new Matching();
+
private SoftTimeout softTimeout = new SoftTimeout();
public Ranking(Query parent) {
@@ -172,6 +177,9 @@ public class Ranking implements Cloneable {
/** Returns the match phase rank settings of this. This is never null. */
public MatchPhase getMatchPhase() { return matchPhase; }
+ /** Returns the matching settings of this. This is never null. */
+ public Matching getMatching() { return matching; }
+
/** Returns the soft timeout settings of this. This is never null. */
public SoftTimeout getSoftTimeout() { return softTimeout; }
@@ -185,6 +193,7 @@ public class Ranking implements Cloneable {
clone.rankProperties = this.rankProperties.clone();
clone.rankFeatures = this.rankFeatures.clone();
clone.matchPhase = this.matchPhase.clone();
+ clone.matching = this.matching.clone();
clone.softTimeout = this.softTimeout.clone();
return clone;
}
@@ -216,6 +225,7 @@ public class Ranking implements Cloneable {
hash += 13 * rankProperties.hashCode();
hash += 17 * matchPhase.hashCode();
hash += 19 * softTimeout.hashCode();
+ hash += 23 * matching.hashCode();
return Ranking.class.hashCode() + QueryHelper.combineHash(sorting,location,profile,hash);
}
@@ -240,6 +250,7 @@ public class Ranking implements Cloneable {
public void prepare() {
rankFeatures.prepare(rankProperties);
matchPhase.prepare(rankProperties);
+ matching.prepare(rankProperties);
softTimeout.prepare(rankProperties);
prepareNow(freshness);
}
diff --git a/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java b/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java
index 30154b223a5..dbbb9977e05 100644
--- a/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java
+++ b/container-search/src/main/java/com/yahoo/search/query/properties/QueryProperties.java
@@ -1,16 +1,16 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.query.properties;
-import com.yahoo.component.ComponentId;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.Query;
import com.yahoo.search.query.*;
import com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry;
import com.yahoo.search.query.profile.types.FieldDescription;
import com.yahoo.search.query.profile.types.QueryProfileType;
-import com.yahoo.search.query.profile.types.QueryProfileTypeRegistry;
import com.yahoo.search.query.ranking.Diversity;
import com.yahoo.search.query.ranking.MatchPhase;
+import com.yahoo.search.query.ranking.Matching;
+import com.yahoo.search.query.ranking.SoftTimeout;
import com.yahoo.tensor.Tensor;
import java.util.Map;
@@ -119,6 +119,14 @@ public class QueryProperties extends Properties {
if (key.last().equals(SoftTimeout.FACTOR)) return soft.getFactor();
if (key.last().equals(SoftTimeout.TAILCOST)) return soft.getTailcost();
}
+ else if (key.size() == 3 && key.get(1).equals(Ranking.MATCHING)) {
+ Matching matching = ranking.getMatching();
+ if (key.last().equals(Matching.TERMWISELIMIT)) return matching.getTermwiseLimit();
+ if (key.last().equals(Matching.NUMTHREADSPERSEARCH)) return matching.getNumThreadsPerSearch();
+ if (key.last().equals(Matching.NUMSEARCHPARTITIIONS)) return matching.getNumSearchPartitions();
+ if (key.last().equals(Matching.MINHITSPERTHREAD)) return matching.getMinHitsPerThread();
+
+ }
else if (key.size()>2) {
// pass the portion after "ranking.features/properties" down
if (key.get(1).equals(Ranking.FEATURES)) return ranking.getFeatures().getObject(key.rest().rest().toString());
@@ -228,6 +236,13 @@ public class QueryProperties extends Properties {
if (key.last().equals(SoftTimeout.FACTOR)) soft.setFactor(asDouble(value, 0.50));
if (key.last().equals(SoftTimeout.TAILCOST)) soft.setTailcost(asDouble(value, 0.10));
}
+ else if (key.size() == 3 && key.get(1).equals(Ranking.MATCHING)) {
+ Matching matching = ranking.getMatching();
+ if (key.last().equals(Matching.TERMWISELIMIT)) matching.setTermwiselimit(asDouble(value, 1.0));
+ if (key.last().equals(Matching.NUMTHREADSPERSEARCH)) matching.setNumThreadsPerSearch(asInteger(value, 1));
+ if (key.last().equals(Matching.NUMSEARCHPARTITIIONS)) matching.setNumSearchPartitions(asInteger(value, 1));
+ if (key.last().equals(Matching.MINHITSPERTHREAD)) matching.setMinHitsPerThread(asInteger(value, 0));
+ }
else if (key.size()>2) {
String restKey = key.rest().rest().toString();
if (key.get(1).equals(Ranking.FEATURES))
diff --git a/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java b/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java
new file mode 100644
index 00000000000..514a0f36031
--- /dev/null
+++ b/container-search/src/main/java/com/yahoo/search/query/ranking/Matching.java
@@ -0,0 +1,123 @@
+package com.yahoo.search.query.ranking;
+
+import com.yahoo.search.query.Ranking;
+import com.yahoo.search.query.profile.types.FieldDescription;
+import com.yahoo.search.query.profile.types.QueryProfileType;
+
+import java.util.Objects;
+
+/**
+ * Holds the settings for the matching feature.
+ *
+ * @author balder
+ */
+public class Matching implements Cloneable {
+ /** The type representing the property arguments consumed by this */
+ private static final QueryProfileType argumentType;
+
+ public static final String TERMWISELIMIT = "termwiselimit";
+ public static final String NUMTHREADSPERSEARCH = "numthreadspersearch";
+ public static final String NUMSEARCHPARTITIIONS = "numsearchpartitions";
+ public static final String MINHITSPERTHREAD = "minhitsperthread";
+
+
+ static {
+ argumentType =new QueryProfileType(Ranking.MATCHING);
+ argumentType.setStrict(true);
+ argumentType.setBuiltin(true);
+ argumentType.addField(new FieldDescription(TERMWISELIMIT, "double"));
+ argumentType.addField(new FieldDescription(NUMTHREADSPERSEARCH, "integer"));
+ argumentType.addField(new FieldDescription(NUMSEARCHPARTITIIONS, "integer"));
+ argumentType.addField(new FieldDescription(MINHITSPERTHREAD, "integer"));
+ argumentType.freeze();
+ }
+ public static QueryProfileType getArgumentType() { return argumentType; }
+
+ public Double termwiseLimit = null;
+ private Integer numThreadsPerSearch = null;
+ private Integer numSearchPartitions = null;
+ private Integer minHitsPerThread = null;
+
+ public Integer getNumSearchPartitions() {
+ return numSearchPartitions;
+ }
+
+ public void setNumSearchPartitions(int numSearchPartitions) {
+ this.numSearchPartitions = numSearchPartitions;
+ }
+
+ public Integer getMinHitsPerThread() {
+ return minHitsPerThread;
+ }
+
+ public void setMinHitsPerThread(int minHitsPerThread) {
+ this.minHitsPerThread = minHitsPerThread;
+ }
+
+ public void setTermwiselimit(double value) {
+ if ((value < 0.0) || (value > 1.0)) {
+ throw new IllegalArgumentException("termwiselimit must be in the range [0.0, 1.0]. It is " + value);
+ }
+ termwiseLimit = value;
+ }
+
+ public Double getTermwiseLimit() { return termwiseLimit; }
+
+ public void setNumThreadsPerSearch(int value) {
+ numThreadsPerSearch = value;
+ }
+ public Integer getNumThreadsPerSearch() { return numThreadsPerSearch; }
+
+
+ /** Internal operation - DO NOT USE */
+ public void prepare(RankProperties rankProperties) {
+
+ if (termwiseLimit != null) {
+ rankProperties.put("vespa.matching.termwise_limit", String.valueOf(termwiseLimit));
+ }
+ if (numThreadsPerSearch != null) {
+ rankProperties.put("vespa.matching.numthreadspersearch", String.valueOf(numThreadsPerSearch));
+ }
+ if (numSearchPartitions != null) {
+ rankProperties.put("vespa.matching.numsearchpartitions", String.valueOf(numSearchPartitions));
+ }
+ if (minHitsPerThread != null) {
+ rankProperties.put("vespa.matching.minhitsperthread", String.valueOf(minHitsPerThread));
+ }
+ }
+
+ @Override
+ public Matching clone() {
+ try {
+ return (Matching) super.clone();
+ }
+ catch (CloneNotSupportedException e) {
+ throw new RuntimeException("Won't happen", e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 0;
+ if (termwiseLimit != null) hash += 11 * termwiseLimit.hashCode();
+ if (numThreadsPerSearch != null) hash += 13 * numThreadsPerSearch.hashCode();
+ if (numSearchPartitions != null) hash += 17 * numSearchPartitions.hashCode();
+ if (minHitsPerThread != null) hash += 19 * minHitsPerThread.hashCode();
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if ( ! (o instanceof Matching)) return false;
+
+ Matching other = (Matching) o;
+ if ( ! Objects.equals(this.termwiseLimit, other.termwiseLimit)) return false;
+ if ( ! Objects.equals(this.numThreadsPerSearch, other.numThreadsPerSearch)) return false;
+ if ( ! Objects.equals(this.numSearchPartitions, other.numSearchPartitions)) return false;
+ if ( ! Objects.equals(this.minHitsPerThread, other.minHitsPerThread)) return false;
+ return true;
+ }
+
+}
+
diff --git a/container-search/src/main/java/com/yahoo/search/query/SoftTimeout.java b/container-search/src/main/java/com/yahoo/search/query/ranking/SoftTimeout.java
index 2db1235f72c..950cb861da6 100644
--- a/container-search/src/main/java/com/yahoo/search/query/SoftTimeout.java
+++ b/container-search/src/main/java/com/yahoo/search/query/ranking/SoftTimeout.java
@@ -1,8 +1,8 @@
-package com.yahoo.search.query;
+package com.yahoo.search.query.ranking;
+import com.yahoo.search.query.Ranking;
import com.yahoo.search.query.profile.types.FieldDescription;
import com.yahoo.search.query.profile.types.QueryProfileType;
-import com.yahoo.search.query.ranking.RankProperties;
import java.util.Objects;
diff --git a/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java b/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java
new file mode 100644
index 00000000000..49e632b00bd
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/query/MatchingTestCase.java
@@ -0,0 +1,54 @@
+package com.yahoo.search.query;
+
+import com.yahoo.prelude.query.QueryException;
+import com.yahoo.search.Query;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author baldersheim
+ */
+public class MatchingTestCase {
+ @Test
+ public void testDefaultsInQuery() {
+ Query query=new Query("?query=test");
+ assertNull(query.getRanking().getMatching().getTermwiseLimit());
+ assertNull(query.getRanking().getMatching().getNumThreadsPerSearch());
+ assertNull(query.getRanking().getMatching().getNumSearchPartitions());
+ assertNull(query.getRanking().getMatching().getMinHitsPerThread());
+
+ }
+
+ @Test
+ public void testQueryOverride() {
+ Query query=new Query("?query=test&ranking.matching.termwiselimit=0.7&ranking.matching.numthreadspersearch=17&ranking.matching.numsearchpartitions=13&ranking.matching.minhitsperthread=3");
+ assertEquals(Double.valueOf(0.7), query.getRanking().getMatching().getTermwiseLimit());
+ assertEquals(Integer.valueOf(17), query.getRanking().getMatching().getNumThreadsPerSearch());
+ assertEquals(Integer.valueOf(13), query.getRanking().getMatching().getNumSearchPartitions());
+ assertEquals(Integer.valueOf(3), query.getRanking().getMatching().getMinHitsPerThread());
+
+ query.prepare();
+ assertEquals("0.7", query.getRanking().getProperties().get("vespa.matching.termwise_limit").get(0));
+ assertEquals("17", query.getRanking().getProperties().get("vespa.matching.numthreadspersearch").get(0));
+ assertEquals("13", query.getRanking().getProperties().get("vespa.matching.numsearchpartitions").get(0));
+ assertEquals("3", query.getRanking().getProperties().get("vespa.matching.minhitsperthread").get(0));
+ }
+
+ private void verifyException(String key, String value) {
+ try {
+ new Query("?query=test&ranking.matching."+key+"="+value);
+ assertFalse(true);
+ } catch (QueryException e) {
+ assertEquals("Invalid request parameter", e.getMessage());
+ assertEquals("Could not set 'ranking.matching." + key + "' to '" + value +"'", e.getCause().getMessage());
+ assertEquals(key + " must be in the range [0.0, 1.0]. It is " + value, e.getCause().getCause().getMessage());
+ }
+ }
+ @Test
+ public void testLimits() {
+ verifyException("termwiselimit", "-0.1");
+ verifyException("termwiselimit", "1.1");
+ }
+}