Solr除了支持通过各种查询参数查询索引外,还支持通过Lucene查询语法的变体进行查询。
例如:
{!lucene q.op=AND df=text sort=’price asc’}myfield:foo +bar -baz
该查询语句中的”foo +bar -baz”部分需要进行词法分析和语法分析。
Solr采取了与Lucene相同的词法/语法解析方法:即通过JavaCC自动生成词法/语法解析代码。关于JavaCC的知识可以参考以下两篇文章:JavaCC–Linux安装与使用和JavaCC – 生成C++代码。
(1)注册LuceneQParserPlugin
public abstract class QParserPlugin implements NamedListInitializedPlugin, SolrInfoMBean {
/** internal use - name of the default parser */
public static final String DEFAULT_QTYPE = LuceneQParserPlugin.NAME;
static {
HashMap<String, Class<? extends QParserPlugin>> map = new HashMap<>(30, 1);
'''第一种类型不包含排序参数:!lucene q.op=AND df=text sort='price asc'}myfield:foo +bar -baz'''
map.put(LuceneQParserPlugin.NAME, LuceneQParserPlugin.class);
'''第二种类型包含排序参数:{!lucenePlusSort}myfield:foo +bar -baz;price asc'''
map.put(OldLuceneQParserPlugin.NAME, OldLuceneQParserPlugin.class);
.....
}
}
(2)创建Parser
public class LuceneQParserPlugin extends QParserPlugin {
public static final String NAME = "lucene";
@Override
public QParser createParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest req) {
return new LuceneQParser(qstr, localParams, params, req);
}
}
public class LuceneQParser extends QParser {
'''SolrQueryParser是JavaCC生成的QueryParser类的子类'''
SolrQueryParser lparser;
@Override
public Query parse() throws SyntaxError {
String qstr = getString();
if (qstr == null || qstr.length()==0) return null;
String defaultField = getParam(CommonParams.DF);
if (defaultField==null) {
defaultField = getReq().getSchema().getDefaultSearchFieldName();
}
lparser = new SolrQueryParser(this, defaultField);
lparser.setDefaultOperator
(QueryParsing.getQueryParserDefaultOperator(getReq().getSchema(),
getParam(QueryParsing.OP)));
'''调用父类QueryParser的parse方法解析'''
return lparser.parse(qstr);
}
}
(3)JavaCC生成的QueryParser类,Lucene也有同样的类
public class QueryParser extends SolrQueryParserBase implements QueryParserConstants {
'''在parse()方法调用,此函数是在JavaCC的输入文件XXX.jj中定义,并由JavaCC生成'''
final public Query TopLevelQuery(String field) throws ParseException, SyntaxError {
Query q;
q = Query(field);
jj_consume_token(0);
{if (true) return q;}
throw new Error("Missing return statement in function");
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/zhufenglonglove/article/details/51461837
内容来源于网络,如有侵权,请联系作者删除!