欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

solr的facet源码解读(一)——facet.query

程序员文章站 2022-04-03 19:16:06
...

solr的facet query意思很简单,表示在所有的搜索到的结果中,符合某个query的doc有多少个。他的实现原理也很简单。

solr中所有的facet的操作都在facetComponent中,在这个类的process方法里面,会将facet委托给SimpleFacet这个类,然后调用simpleFacet.getFacetCounts方法。我们要说的facet.query就是在这个类中,如下:

public NamedList<Object> getFacetCounts() {
	// if someone called this method, benefit of the doubt: assume true
	if (!params.getBool(FacetParams.FACET, true))
		return null;

	facetResponse = new SimpleOrderedMap<>();
	try {
		facetResponse.add("facet_queries", getFacetQueryCounts());
		facetResponse.add("facet_fields", getFacetFieldCounts()); //
		facetResponse.add("facet_ranges", getFacetRangeCounts());
		facetResponse.add("facet_intervals", getFacetIntervalCounts());

	} catch (IOException e) {
		throw new SolrException(ErrorCode.SERVER_ERROR, e);
	} catch (SyntaxError e) {
		throw new SolrException(ErrorCode.BAD_REQUEST, e);
	}
	return facetResponse;
}

 可以发现,所有的facet的操作都是在这个类中,包括facetQuery、facetField、facetRange,在工作中最常用的就是facetQuery、facetField,先看下facetQuery吧

public NamedList<Integer> getFacetQueryCounts() throws IOException, SyntaxError {
	NamedList<Integer> res = new SimpleOrderedMap<>();
	String[] facetQs = params.getParams(FacetParams.FACET_QUERY);
	if (null != facetQs && 0 != facetQs.length) {
		for (String q : facetQs) {//轮训所有的facet的query
			parseParams(FacetParams.FACET_QUERY, q);//这个方法很简单,就是将一些参数保存到这个类的属性里面,比如下面的docs,
			// TODO: slight optimization would prevent double-parsing of any localParams
			Query qobj = QParser.getParser(q, null, req).getQuery();//获得facet.query的query是什么。
			if (qobj == null) {
				res.add(key, 0);
			} else if (params.getBool(GroupParams.GROUP_FACET, false)) {//这个我没有看,因为工作中还没有遇到这个功能。以后很可能会补充上。
				res.add(key, getGroupedFacetQueryCount(qobj));
			} else {
				res.add(key, searcher.numDocs(qobj, docs));//searcher.numDocs很简单,就是使用这个qobj命中的docs和第二个参数docs取交集,返回的是交集中的数量,第二个参数是solr的参数中q和fq中的命中的doc的id的集合。并且这个方法中会使用filterCache,所以facet.query是很高效的,它仅仅会涉及到倒排表的合并,并且还会使用到filterCache。
			}
		}
	}
	return res;
}

 如此简单就看懂了facet.query的实现原理,他的实现还是很高效的,可以大胆的使用。

  

相关标签: solr facet