SOLR-9682: add param query type to facet filter

This commit is contained in:
yonik 2016-11-05 15:24:57 -04:00
parent 1f1990d8be
commit 4b3e7f2fe2
3 changed files with 74 additions and 11 deletions

View File

@ -98,6 +98,9 @@ New Features
* SOLR-9055: Make collection backup/restore extensible. (Hrishikesh Gadre, Varun Thacker, Mark Miller)
* SOLR-9682: JSON Facet API: added "param" query type to facet domain filter specification to obtain
filters via query parameters. (yonik)
Optimizations
----------------------
* SOLR-9704: Facet Module / JSON Facet API: Optimize blockChildren facets that have

View File

@ -94,20 +94,58 @@ public abstract class FacetProcessor<FacetRequestT extends FacetRequest> {
List<Query> qlist = new ArrayList<>(freq.domain.filters.size());
// TODO: prevent parsing filters each time!
for (Object rawFilter : freq.domain.filters) {
Query symbolicFilter;
if (rawFilter instanceof String) {
QParser parser = null;
try {
parser = QParser.getParser((String)rawFilter, fcontext.req);
symbolicFilter = parser.getQuery();
Query symbolicFilter = parser.getQuery();
qlist.add(symbolicFilter);
} catch (SyntaxError syntaxError) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, syntaxError);
}
} else if (rawFilter instanceof Map) {
Map<String,Object> m = (Map<String, Object>) rawFilter;
String type;
Object args;
if (m.size() == 1) {
Map.Entry<String, Object> entry = m.entrySet().iterator().next();
type = entry.getKey();
args = entry.getValue();
} else {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Can't convert map to query:" + rawFilter);
}
if (!"param".equals(type)) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Unknown type. Can't convert map to query:" + rawFilter);
}
String tag;
if (!(args instanceof String)) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Can't retrieve non-string param:" + args);
}
tag = (String)args;
String[] qstrings = fcontext.req.getParams().getParams(tag);
if (qstrings != null) {
for (String qstring : qstrings) {
QParser parser = null;
try {
parser = QParser.getParser((String) qstring, fcontext.req);
Query symbolicFilter = parser.getQuery();
qlist.add(symbolicFilter);
} catch (SyntaxError syntaxError) {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, syntaxError);
}
}
}
} else {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Bad query (expected a string):" + rawFilter);
}
qlist.add(symbolicFilter);
}
this.filter = fcontext.searcher.getDocSet(qlist);

View File

@ -1165,26 +1165,30 @@ public class TestJsonFacets extends SolrTestCaseHS {
// test filter
client.testJQ(params(p, "q", "*:*", "myfilt","${cat_s}:A"
client.testJQ(params(p, "q", "*:*", "myfilt","${cat_s}:A", "ff","-id:1", "ff","-id:2"
, "json.facet", "{" +
"t:{${terms} type:terms, field:${cat_s}, domain:{filter:[]} }" + // empty filter list
",t_filt:{${terms} type:terms, field:${cat_s}, domain:{filter:'${cat_s}:B'} }" +
",t_filt2:{${terms} type:terms, field:${cat_s}, domain:{filter:'{!query v=$myfilt}'} }" + // test access to qparser and other query parameters
",t_filt3:{${terms} type:terms, field:${cat_s}, domain:{filter:['-id:1','-id:2']} }" +
",t_filt2 :{${terms} type:terms, field:${cat_s}, domain:{filter:'{!query v=$myfilt}'} }" + // test access to qparser and other query parameters
",t_filt2a:{${terms} type:terms, field:${cat_s}, domain:{filter:{param:myfilt} } }" + // test filter via "param" type
",t_filt3: {${terms} type:terms, field:${cat_s}, domain:{filter:['-id:1','-id:2']} }" +
",t_filt3a:{${terms} type:terms, field:${cat_s}, domain:{filter:{param:ff}} }" + // test multi-valued query parameter
",q:{type:query, q:'${cat_s}:B', domain:{filter:['-id:5']} }" + // also tests a top-level negative filter
",r:{type:range, field:${num_d}, start:-5, end:10, gap:5, domain:{filter:'-id:4'} }" +
"}"
)
, "facets=={ count:6, " +
"t :{ buckets:[ {val:B, count:3}, {val:A, count:2} ] }" +
",t_filt :{ buckets:[ {val:B, count:3}] } " +
",t_filt2:{ buckets:[ {val:A, count:2}] } " +
",t_filt3:{ buckets:[ {val:B, count:2}, {val:A, count:1}] } " +
"t :{ buckets:[ {val:B, count:3}, {val:A, count:2} ] }" +
",t_filt :{ buckets:[ {val:B, count:3}] } " +
",t_filt2 :{ buckets:[ {val:A, count:2}] } " +
",t_filt2a:{ buckets:[ {val:A, count:2}] } " +
",t_filt3 :{ buckets:[ {val:B, count:2}, {val:A, count:1}] } " +
",t_filt3a:{ buckets:[ {val:B, count:2}, {val:A, count:1}] } " +
",q:{count:2}" +
",r:{buckets:[ {val:-5.0,count:1}, {val:0.0,count:1}, {val:5.0,count:0} ] }" +
"}"
);
}
@Test
@ -1433,6 +1437,24 @@ public class TestJsonFacets extends SolrTestCaseHS {
"}"
);
// test other various ways to get filters
client.testJQ(params(p, "q", "*:*", "f1","-id:3.1", "f2","id:1"
, "json.facet", "{ " +
"pages1:{type:terms, field:v_t, domain:{blockChildren:'type_s:book', filter:[]} }" +
",pages2:{type:terms, field:v_t, domain:{blockChildren:'type_s:book', filter:{param:f1} } }" +
",books:{type:terms, field:v_t, domain:{blockParent:'type_s:book', filter:[{param:q},{param:missing_param}]} }" +
",books2:{type:terms, field:v_t, domain:{blockParent:'type_s:book', filter:[{param:f2}] } }" +
"}"
)
, "facets=={ count:10" +
", pages1:{ buckets:[ {val:y,count:4},{val:x,count:3},{val:z,count:3} ] }" +
", pages2:{ buckets:[ {val:y,count:4},{val:z,count:3},{val:x,count:2} ] }" +
", books:{ buckets:[ {val:q,count:3},{val:e,count:2},{val:w,count:2} ] }" +
", books2:{ buckets:[ {val:q,count:1} ] }" +
"}"
);
}