SOLR-10283: Learning to Rank (LTR) SolrFeature to reject searches with missing efi (External Feature Information) used by fq.

This commit is contained in:
Christine Poerschke 2017-03-16 14:10:28 +00:00 committed by Shalin Shekhar Mangar
parent d836ff1da5
commit 9f935735b0
5 changed files with 39 additions and 6 deletions

View File

@ -260,6 +260,9 @@ Bug Fixes
* SOLR-10302: Solr's zkcli scripts now able to find the metrics libraries, which it couldn't earlier (kiran, Ishan Chattopadhyaya)
* SOLR-10283: Learning to Rank (LTR) SolrFeature to reject searches with missing efi (External Feature Information) used by fq.
(Christine Poerschke)
Optimizations
----------------------

View File

@ -157,6 +157,9 @@ public class SolrFeature extends Feature {
for (String fq : fqs) {
if ((fq != null) && (fq.trim().length() != 0)) {
fq = macroExpander.expand(fq);
if (fq == null) {
throw new FeatureException(this.getClass().getSimpleName()+" requires efi parameter that was not passed in request.");
}
final QParser fqp = QParser.getParser(fq, req);
final Query filterQuery = fqp.getQuery();
if (filterQuery != null) {

View File

@ -48,4 +48,10 @@
"params" : {
"q" : "{!field f=title}${user_query}"
}
}, {
"name" : "titlePhrasesMatch",
"class" : "org.apache.solr.ltr.feature.SolrFeature",
"params" : {
"fq" : [ "{!field f=title}${userTitlePhrase1}", "{!field f=title}${userTitlePhrase2}"]
}
} ]

View File

@ -210,18 +210,22 @@ public class TestSelectiveWeightCreation extends TestRerankBase {
@Test
public void testSelectiveWeightsRequestFeaturesFromDifferentStore() throws Exception {
final String docs0fv = FeatureLoggerTestUtils.toFeatureVector(
final String docs0fv_sparse = FeatureLoggerTestUtils.toFeatureVector(
"matchedTitle","1.0", "titlePhraseMatch","0.6103343");
final String docs0fv_dense = FeatureLoggerTestUtils.toFeatureVector(
"matchedTitle","1.0", "titlePhraseMatch","0.6103343", "titlePhrasesMatch","0.0");
final String docs0fv_fstore4= FeatureLoggerTestUtils.toFeatureVector(
"popularity","3.0", "originalScore","1.0");
final String docs0fv = chooseDefaultFeatureVector(docs0fv_dense, docs0fv_sparse);
// extract all features in externalmodel's store (default store)
// rerank using externalmodel (default store)
final SolrQuery query = new SolrQuery();
query.setQuery("*:*");
query.add("fl", "*,score,fv:[fv]");
query.add("rows", "5");
query.add("rq", "{!ltr reRankDocs=10 model=externalmodel efi.user_query=w3}");
query.add("rq", "{!ltr reRankDocs=10 model=externalmodel efi.user_query=w3 efi.userTitlePhrase1=w2 efi.userTitlePhrase2=w1}");
assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='3'");
assertJQ("/query" + query.toQueryString(), "/response/docs/[1]/id=='4'");

View File

@ -67,7 +67,7 @@ public class TestExternalFeatures extends TestRerankBase {
query.remove("fl");
query.add("fl", "*,score,[fv]");
query.add("rq", "{!ltr reRankDocs=10 model=externalmodel efi.user_query=w3}");
query.add("rq", "{!ltr reRankDocs=10 model=externalmodel efi.user_query=w3 efi.userTitlePhrase1=w4 efi.userTitlePhrase2=w5}");
assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='3'");
assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/score==0.7693934");
@ -77,7 +77,7 @@ public class TestExternalFeatures extends TestRerankBase {
// Adding an efi in the transformer should not affect the rq ranking with a
// different value for efi of the same parameter
query.remove("fl");
query.add("fl", "*,score,[fv efi.user_query=w2]");
query.add("fl", "*,score,[fv efi.user_query=w2 efi.userTitlePhrase1=w4 efi.userTitlePhrase2=w5]");
assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/id=='3'");
assertJQ("/query" + query.toQueryString(), "/response/docs/[0]/score==0.7693934");
@ -92,11 +92,12 @@ public class TestExternalFeatures extends TestRerankBase {
query.add("fl", "*,score,fv:[fv]");
query.add("rows", "1");
// Stopword only query passed in
query.add("rq", "{!ltr reRankDocs=10 model=externalmodel efi.user_query='a'}");
query.add("rq", "{!ltr reRankDocs=10 model=externalmodel efi.user_query='a' efi.userTitlePhrase1='b' efi.userTitlePhrase2='c'}");
final String docs0fv_dense_csv = FeatureLoggerTestUtils.toFeatureVector(
"matchedTitle","0.0",
"titlePhraseMatch","0.0");
"titlePhraseMatch","0.0",
"titlePhrasesMatch","0.0");
final String docs0fv_sparse_csv = FeatureLoggerTestUtils.toFeatureVector();
final String docs0fv_default_csv = chooseDefaultFeatureVector(docs0fv_dense_csv, docs0fv_sparse_csv);
@ -181,4 +182,20 @@ public class TestExternalFeatures extends TestRerankBase {
query.add("fl", "fvalias:[fv store=fstore4]");
assertJQ("/query" + query.toQueryString(), "/error/msg=='Exception from createWeight for ValueFeature [name=popularity, params={value=${myPop}, required=true}] ValueFeatureWeight requires efi parameter that was not passed in request.'");
}
@Test
public void featureExtraction_valueFeatureRequiredInFq_shouldThrowException() throws Exception {
final String userTitlePhrase1 = "userTitlePhrase1";
final String userTitlePhrase2 = "userTitlePhrase2";
final String userTitlePhrasePresent = (random().nextBoolean() ? userTitlePhrase1 : userTitlePhrase2);
final SolrQuery query = new SolrQuery();
query.setQuery("*:*");
query.add("rows", "1");
query.add("fl", "score,features:[fv efi.user_query=uq "+userTitlePhrasePresent+"=utpp]");
assertJQ("/query" + query.toQueryString(), "/error/msg=='Exception from createWeight for "
+ "SolrFeature [name=titlePhrasesMatch, params={fq=[{!field f=title}${"+userTitlePhrase1+"}, {!field f=title}${"+userTitlePhrase2+"}]}] "
+ "SolrFeatureWeight requires efi parameter that was not passed in request.'");
}
}