SOLR-334: change local params syntax from angle brackets to curly braces

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@652124 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2008-04-29 21:07:25 +00:00
parent 4a8ca8f13a
commit dd8974c32f
5 changed files with 49 additions and 46 deletions

View File

@ -292,7 +292,7 @@ public class FacetComponent extends SearchComponent
String facet_q = (String)facet_queries.getName(i); String facet_q = (String)facet_queries.getName(i);
long count = ((Number)facet_queries.getVal(i)).longValue(); long count = ((Number)facet_queries.getVal(i)).longValue();
// expect <!field f=field>value style params // expect {!field f=field}value style params
SolrParams qparams = QueryParsing.getLocalParams(facet_q,null); SolrParams qparams = QueryParsing.getLocalParams(facet_q,null);
String field = qparams.get(QueryParsing.F); String field = qparams.get(QueryParsing.F);
String val = qparams.get(QueryParsing.V); String val = qparams.get(QueryParsing.V);
@ -302,7 +302,7 @@ public class FacetComponent extends SearchComponent
// Find the right constraint count for this value // Find the right constraint count for this value
ShardFacetCount sfc = dff.counts.get(val); ShardFacetCount sfc = dff.counts.get(val);
// TODO REMOVE // TODO REMOVE
System.out.println("Got " + facet_q + " , refining count: " + sfc + " += " + count); // System.out.println("Got " + facet_q + " , refining count: " + sfc + " += " + count);
sfc.count += count; sfc.count += count;
@ -490,7 +490,7 @@ class DistribFieldFacet extends FieldFacet {
sf = rb.req.getSchema().getField(field); sf = rb.req.getSchema().getField(field);
missingMax = new long[rb.shards.length]; missingMax = new long[rb.shards.length];
counted = new OpenBitSet[rb.shards.length]; counted = new OpenBitSet[rb.shards.length];
queryPrefix = "<!field f=" + field + '>'; queryPrefix = "{!field f=" + field + '}';
} }
void add(int shardNum, NamedList shardCounts, int numRequested) { void add(int shardNum, NamedList shardCounts, int numRequested) {

View File

@ -155,7 +155,7 @@ public class FunctionQParser extends QParser {
throw new ParseException("Nested local params must have value in v parameter. got '" + qs + "'"); throw new ParseException("Nested local params must have value in v parameter. got '" + qs + "'");
} }
} else { } else {
throw new ParseException("Nested function query must use $param or <!v=value> forms. got '" + qs + "'"); throw new ParseException("Nested function query must use $param or {!v=value} forms. got '" + qs + "'");
} }
sp.pos += end-start; // advance past nested query sp.pos += end-start; // advance past nested query

View File

@ -52,6 +52,8 @@ public class QueryParsing {
public static final String F = "f"; // field that a query or command pertains to public static final String F = "f"; // field that a query or command pertains to
public static final String TYPE = "type";// type of this query or command public static final String TYPE = "type";// type of this query or command
public static final String DEFTYPE = "defType"; // default type for any direct subqueries public static final String DEFTYPE = "defType"; // default type for any direct subqueries
public static final String LOCALPARAM_START = "{!";
public static final char LOCALPARAM_END = '}';
/** /**
* Helper utility for parsing a query using the Lucene QueryParser syntax. * Helper utility for parsing a query using the Lucene QueryParser syntax.
@ -116,31 +118,31 @@ public class QueryParsing {
// note to self: something needs to detect infinite recursion when parsing queries // note to self: something needs to detect infinite recursion when parsing queries
static int parseLocalParams(String txt, int start, Map<String,String> target, SolrParams params) throws ParseException { static int parseLocalParams(String txt, int start, Map<String,String> target, SolrParams params) throws ParseException {
int off=start; int off=start;
if (!txt.startsWith("<!",off)) return start; if (!txt.startsWith(LOCALPARAM_START,off)) return start;
StrParser p = new StrParser(txt,start,txt.length()); StrParser p = new StrParser(txt,start,txt.length());
p.pos+=2; // skip over "<!" p.pos+=2; // skip over "{!"
for(;;) { for(;;) {
/* /*
if (p.pos>=txt.length()) { if (p.pos>=txt.length()) {
throw new ParseException("Missing '>' parsing local params '" + txt + '"'); throw new ParseException("Missing '}' parsing local params '" + txt + '"');
} }
*/ */
char ch = p.peek(); char ch = p.peek();
if (ch=='>') { if (ch==LOCALPARAM_END) {
return p.pos+1; return p.pos+1;
} }
String id = p.getId(); String id = p.getId();
if (id.length()==0) { if (id.length()==0) {
throw new ParseException("Expected identifier '>' parsing local params '" + txt + '"'); throw new ParseException("Expected identifier '}' parsing local params '" + txt + '"');
} }
String val=null; String val=null;
ch = p.peek(); ch = p.peek();
if (ch!='=') { if (ch!='=') {
// single word... treat <!func> as ""=func for easy lookup // single word... treat {!func} as type=func for easy lookup
val = id; val = id;
id = TYPE; id = TYPE;
} else { } else {
@ -157,7 +159,7 @@ public class QueryParsing {
val = params.get(pname); val = params.get(pname);
} }
} else { } else {
// read unquoted literal ended by whitespace or '>' // read unquoted literal ended by whitespace or '}'
// there is no escaping. // there is no escaping.
int valStart = p.pos; int valStart = p.pos;
for (;;) { for (;;) {
@ -165,7 +167,7 @@ public class QueryParsing {
throw new ParseException("Missing end to unquoted value starting at " + valStart + " str='" + txt +"'"); throw new ParseException("Missing end to unquoted value starting at " + valStart + " str='" + txt +"'");
} }
char c = p.val.charAt(p.pos); char c = p.val.charAt(p.pos);
if (c=='>' || Character.isWhitespace(c)) { if (c==LOCALPARAM_END || Character.isWhitespace(c)) {
val = p.val.substring(valStart, p.pos); val = p.val.substring(valStart, p.pos);
break; break;
} }
@ -179,11 +181,11 @@ public class QueryParsing {
/** /**
* "foo" returns null * "foo" returns null
* "<!prefix f=myfield>yes" returns type="prefix",f="myfield",v="yes" * "{!prefix f=myfield}yes" returns type="prefix",f="myfield",v="yes"
* "<!prefix f=myfield v=$p>" returns type="prefix",f="myfield",v=params.get("p") * "{!prefix f=myfield v=$p}" returns type="prefix",f="myfield",v=params.get("p")
*/ */
public static SolrParams getLocalParams(String txt, SolrParams params) throws ParseException { public static SolrParams getLocalParams(String txt, SolrParams params) throws ParseException {
if (txt==null || !txt.startsWith("<!")) { if (txt==null || !txt.startsWith(LOCALPARAM_START)) {
return null; return null;
} }
Map<String,String> localParams = new HashMap<String,String>(); Map<String,String> localParams = new HashMap<String,String>();

View File

@ -453,8 +453,8 @@ public class TestDistributedSearch extends TestCase {
// these queries should be exactly ordered and scores should exactly match // these queries should be exactly ordered and scores should exactly match
query("q","*:*", "sort",i1+" desc"); query("q","*:*", "sort",i1+" desc");
query("q","<!func>"+i1); query("q","{!func}"+i1);
query("q","<!func>"+i1, "fl","*,score"); // even scores should match exactly here query("q","{!func}"+i1, "fl","*,score"); // even scores should match exactly here
handle.put("highlighting", UNORDERED); handle.put("highlighting", UNORDERED);
handle.put("response", UNORDERED); handle.put("response", UNORDERED);

View File

@ -24,6 +24,7 @@ public class TestQueryTypes extends AbstractSolrTestCase {
public String getSolrConfigFile() { return "solrconfig.xml"; } public String getSolrConfigFile() { return "solrconfig.xml"; }
public String getCoreName() { return "basic"; } public String getCoreName() { return "basic"; }
public void setUp() throws Exception { public void setUp() throws Exception {
// if you override setUp or tearDown, you better call // if you override setUp or tearDown, you better call
// the super classes version // the super classes version
@ -39,7 +40,7 @@ public class TestQueryTypes extends AbstractSolrTestCase {
public void testQueryTypes() { public void testQueryTypes() {
assertU(adoc("id","1", "v_t","Hello Dude")); assertU(adoc("id","1", "v_t","Hello Dude"));
assertU(adoc("id","2", "v_t","Hello Yonik")); assertU(adoc("id","2", "v_t","Hello Yonik"));
assertU(adoc("id","3", "v_s","<!literal>")); assertU(adoc("id","3", "v_s","{!literal}"));
assertU(adoc("id","4", "v_s","other stuff")); assertU(adoc("id","4", "v_s","other stuff"));
assertU(adoc("id","5", "v_f","3.14159")); assertU(adoc("id","5", "v_f","3.14159"));
assertU(adoc("id","6", "v_f","8983")); assertU(adoc("id","6", "v_f","8983"));
@ -49,105 +50,105 @@ public class TestQueryTypes extends AbstractSolrTestCase {
// Some basic tests to ensure that parsing local params is working // Some basic tests to ensure that parsing local params is working
assertQ("test prefix query", assertQ("test prefix query",
req("q","<!prefix f=v_t>hel") req("q","{!prefix f=v_t}hel")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test raw query", assertQ("test raw query",
req("q","<!raw f=v_t>hello") req("q","{!raw f=v_t}hello")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test raw query", assertQ("test raw query",
req("q","<!raw f=v_t>Hello") req("q","{!raw f=v_t}Hello")
,"//result[@numFound='0']" ,"//result[@numFound='0']"
); );
assertQ("test raw query", assertQ("test raw query",
req("q","<!raw f=v_f>1.5") req("q","{!raw f=v_f}1.5")
,"//result[@numFound='0']" ,"//result[@numFound='0']"
); );
assertQ("test custom plugin query", assertQ("test custom plugin query",
req("q","<!foo f=v_t>hello") req("q","{!foo f=v_t}hello")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test single term field query on text type", assertQ("test single term field query on text type",
req("q","<!field f=v_t>HELLO") req("q","{!field f=v_t}HELLO")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test single term field query on type with diff internal rep", assertQ("test single term field query on type with diff internal rep",
req("q","<!field f=v_f>1.5") req("q","{!field f=v_f}1.5")
,"//result[@numFound='1']" ,"//result[@numFound='1']"
); );
assertQ("test multi term field query on text type", assertQ("test multi term field query on text type",
req("q","<!field f=v_t>Hello DUDE") req("q","{!field f=v_t}Hello DUDE")
,"//result[@numFound='1']" ,"//result[@numFound='1']"
); );
assertQ("test prefix query with value in local params", assertQ("test prefix query with value in local params",
req("q","<!prefix f=v_t v=hel>") req("q","{!prefix f=v_t v=hel}")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test optional quotes", assertQ("test optional quotes",
req("q","<!prefix f='v_t' v=\"hel\">") req("q","{!prefix f='v_t' v=\"hel\"}")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test extra whitespace", assertQ("test extra whitespace",
req("q","<!prefix f=v_t v=hel >") req("q","{!prefix f=v_t v=hel }")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test literal with <! in it", assertQ("test literal with {! in it",
req("q","<!prefix f=v_s><!lit") req("q","{!prefix f=v_s}{!lit")
,"//result[@numFound='1']" ,"//result[@numFound='1']"
); );
assertQ("test param subst", assertQ("test param subst",
req("q","<!prefix f=$myf v=$my.v>" req("q","{!prefix f=$myf v=$my.v}"
,"myf","v_t", "my.v", "hel" ,"myf","v_t", "my.v", "hel"
) )
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test param subst with literal", assertQ("test param subst with literal",
req("q","<!prefix f=$myf v=$my.v>" req("q","{!prefix f=$myf v=$my.v}"
,"myf","v_s", "my.v", "<!lit" ,"myf","v_s", "my.v", "{!lit"
) )
,"//result[@numFound='1']" ,"//result[@numFound='1']"
); );
// lucene queries // lucene queries
assertQ("test lucene query", assertQ("test lucene query",
req("q","<!lucene>v_t:hel*") req("q","{!lucene}v_t:hel*")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
// lucene queries // lucene queries
assertQ("test lucene default field", assertQ("test lucene default field",
req("q","<!df=v_t>hel*") req("q","{!df=v_t}hel*")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
// lucene operator // lucene operator
assertQ("test lucene operator", assertQ("test lucene operator",
req("q","<!q.op=OR df=v_t>Hello Yonik") req("q","{!q.op=OR df=v_t}Hello Yonik")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test lucene operator", assertQ("test lucene operator",
req("q","<!q.op=AND df=v_t>Hello Yonik") req("q","{!q.op=AND df=v_t}Hello Yonik")
,"//result[@numFound='1']" ,"//result[@numFound='1']"
); );
// test boost queries // test boost queries
assertQ("test boost", assertQ("test boost",
req("q","<!boost b=sum(v_f,1)>id:[5 TO 6]" req("q","{!boost b=sum(v_f,1)}id:[5 TO 6]"
,"fl","*,score" ,"fl","*,score"
) )
,"//result[@numFound='2']" ,"//result[@numFound='2']"
@ -155,8 +156,8 @@ public class TestQueryTypes extends AbstractSolrTestCase {
); );
assertQ("test boost and default type of func", assertQ("test boost and default type of func",
req("q","<!boost v=$q1 b=$q2>" req("q","{!boost v=$q1 b=$q2}"
,"q1", "<!func>v_f", "q2","v_f" ,"q1", "{!func}v_f", "q2","v_f"
,"fl","*,score" ,"fl","*,score"
) )
,"//doc[./float[@name='v_f']='1.5' and ./float[@name='score']='2.25']" ,"//doc[./float[@name='v_f']='1.5' and ./float[@name='score']='2.25']"
@ -165,10 +166,10 @@ public class TestQueryTypes extends AbstractSolrTestCase {
// dismax query from std request handler // dismax query from std request handler
assertQ("test dismax query", assertQ("test dismax query",
req("q","<!dismax>hello" req("q","{!dismax}hello"
,"qf","v_t" ,"qf","v_t"
,"bf","sqrt(v_f)^100 log(sum(v_f,1))^50" ,"bf","sqrt(v_f)^100 log(sum(v_f,1))^50"
,"bq","<!prefix f=v_t>he" ,"bq","{!prefix f=v_t}he"
,"debugQuery","on" ,"debugQuery","on"
) )
,"//result[@numFound='2']" ,"//result[@numFound='2']"
@ -176,19 +177,19 @@ public class TestQueryTypes extends AbstractSolrTestCase {
// dismax query from std request handler, using local params // dismax query from std request handler, using local params
assertQ("test dismax query w/ local params", assertQ("test dismax query w/ local params",
req("q","<!dismax qf=v_t>hello" req("q","{!dismax qf=v_t}hello"
,"qf","v_f" ,"qf","v_f"
) )
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test nested query", assertQ("test nested query",
req("q","_query_:\"<!query v=$q1>\"", "q1","<!prefix f=v_t>hel") req("q","_query_:\"{!query v=$q1}\"", "q1","{!prefix f=v_t}hel")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );
assertQ("test nested nested query", assertQ("test nested nested query",
req("q","_query_:\"<!query defType=query v=$q1>\"", "q1","<!v=$q2>","q2","<!prefix f=v_t v=$qqq>","qqq","hel") req("q","_query_:\"{!query defType=query v=$q1}\"", "q1","{!v=$q2}","q2","{!prefix f=v_t v=$qqq}","qqq","hel")
,"//result[@numFound='2']" ,"//result[@numFound='2']"
); );