Overview
Currently gfsh lucene query can only query with the default StringQueryProvider, which provides syntax as
gfsh> search lucene --name=personIndex --region=/Person --queryString=john* --defaultField=name
StringQueryProvider cannot provide complex search with combination of conditions, especially mixed with numeric range search, for example:
search for a person whose name must contain "john", salary might within 750000 to 80000.
To fulfill the requirement, we will introduce another built-in TermQueryProvider.
Approach
If in gfsh, the user specify one or more --termQuery, then use the new TermQueryProvider
If user also specify --queryString, then it becomes a MUST condition to work together with other --termQuery parameters.
Assumptions
When specifying numeric range, we have to set a few reasonable assumptions to limit the scope of the work.
- In one --termQuery parameter, if one value is float format, then all the numeric value will be treat as float in the --termQuery parameter.
- lower value and high value for range query are both inclusive.
- For numeric query, we only support IntPoint.newRangeQuery and FloatPoint.newRangeQuery
- We have to use --termQuery as parameter of gfsh, so the real condition is put into "()".
Gfsh command line syntax
gfsh> search lucene --name=personIndex --region=/Person --queryString=john* --termQuery=address.must("97006") --termQuery=salary.should([75000,80000]) --defaultField=name Note: find the persons with name starts with "john" and address contain "97006", with his salary might be within 75000 to 80000 (inclusive) gfsh> search lucene --name=personIndex --region=/Person --termQuery=name.should(john*) --termQuery=address.should("97006") --termQuery=salary.should([75000,80000]) --defaultField=name Note: find the persons either name starts with "john" or address contains "97006" or salary are between 75000 to 80000.
Java API
The new TermQueryProvider can be used in java application too.
public class TermRangeQueryProvider implements LuceneQueryProvider /* * @param condition: a list of condition, each to specify a term query */ public TermRangeQueryProvider(String...condition); Here is an example: String condition1 = "name:john*"; // queryString with defailt field String condition2 = "address.should(\"97006\")"; String condition3 = "salary.should([75000,80000])"; TermQueryProvider provider = new TermQueryProvider(condition1, condition2, condition3); LuceneQuery query = service.createLuceneQueryFactory().create(indexName, regionName, provider);