我們看到之前文章Solr 6.0 學習(十四)Solr RequstHandler中的代碼,我們看到有如下片段
if (timer == null) {
for (final SearchComponent c : components) {
c.prepare(rb);
}
}
else {
final RTimerTree subt = timer.sub("prepare");
for (final SearchComponent c2 : components) {
rb.setTimer(subt.sub(c2.getName()));
c2.prepare(rb);
rb.getTimer().stop();
}
subt.stop();
}
SearchComponent 就是我們本篇文章所要講的查詢元件。
SearchComponent 源碼
public abstract class SearchComponent implements SolrInfoMBean, NamedListInitializedPlugin
{
private String name;
public static final Map<String, Class<? extends SearchComponent>> standard_components;
public SearchComponent() {
this.name = this.getClass().getName();
}
/*
預處理
*/
public abstract void prepare(final ResponseBuilder p0) throws IOException;
/*
執行
*/
public abstract void process(final ResponseBuilder p0) throws IOException;
public int distributedProcess(final ResponseBuilder rb) throws IOException {
return ResponseBuilder.STAGE_DONE;
}
public void modifyRequest(final ResponseBuilder rb, final SearchComponent who, final ShardRequest sreq) {
}
public void handleResponses(final ResponseBuilder rb, final ShardRequest sreq) {
}
public void finishStage(final ResponseBuilder rb) {
}
public void setName(final String name) {
this.name = name;
}
@Override
public void init(final NamedList args) {
}
@Override
public String getName() {
return this.name;
}
@Override
public abstract String getDescription();
@Override
public String getSource() {
return null;
}
@Override
public String getVersion() {
return this.getClass().getPackage().getSpecificationVersion();
}
@Override
public Category getCategory() {
return Category.OTHER;
}
@Override
public URL[] getDocs() {
return null;
}
@Override
public NamedList getStatistics() {
return null;
}
static {
final HashMap<String, Class<? extends SearchComponent>> map = new HashMap<String, Class<? extends SearchComponent>>();
map.put("highlight", HighlightComponent.class);
map.put("query", QueryComponent.class);
map.put("facet", FacetComponent.class);
map.put("facet_module", FacetModule.class);
map.put("mlt", MoreLikeThisComponent.class);
map.put("stats", StatsComponent.class);
map.put("debug", DebugComponent.class);
map.put("get", RealTimeGetComponent.class);
map.put("expand", ExpandComponent.class);
standard_components = Collections.unmodifiableMap((Map<? extends String, ? extends Class<? extends SearchComponent>>)map);
}
}
solr預設的查詢元件
在文章Solr 6.0 學習(十四)Solr RequstHandler中的代碼
我們看到如果沒有定義查詢元件的時候會去加載solr預設的查詢元件
/*
*擷取預設查詢元件
*/
protected List<String> getDefaultComponents() {
final ArrayList<String> names = new ArrayList<String>();
names.add("query");
names.add("facet");
names.add("facet_module");
names.add("mlt");
names.add("highlight");
names.add("stats");
names.add("debug");
names.add("expand");
return names;
}
我們找到FacetComponent,截取部分源碼
1、繼承SearchComponent
2、重寫實作prepare和process
@Override
public void prepare(final ResponseBuilder rb) throws IOException {
if (rb.req.getParams().getBool("facet", false)) {
rb.setNeedDocSet(true);
rb.doFacets = true;
final ModifiableSolrParams params = new ModifiableSolrParams();
final SolrParams origParams = rb.req.getParams();
final Iterator<String> iter = (Iterator<String>)origParams.getParameterNamesIterator();
while (iter.hasNext()) {
final String paramName = iter.next();
if (!paramName.startsWith("facet")) {
params.add(paramName, origParams.getParams(paramName));
}
else {
final HashSet<String> deDupe = new LinkedHashSet<String>(Arrays.asList(origParams.getParams(paramName)));
params.add(paramName, (String[])deDupe.toArray(new String[deDupe.size()]));
}
}
rb.req.setParams((SolrParams)params);
FacetContext.initContext(rb);
}
}
@Override
public void process(final ResponseBuilder rb) throws IOException {
if (rb.doFacets) {
final SolrParams params = rb.req.getParams();
final SimpleFacets f = new SimpleFacets(rb.req, rb.getResults().docSet, params, rb);
final NamedList<Object> counts = getFacetCounts(f);
final String[] pivots = params.getParams("facet.pivot");
if (!ArrayUtils.isEmpty((Object[])pivots)) {
final PivotFacetProcessor pivotProcessor = new PivotFacetProcessor(rb.req, rb.getResults().docSet, params, rb);
final SimpleOrderedMap<List<NamedList<Object>>> v = pivotProcessor.process(pivots);
if (v != null) {
counts.add("facet_pivot", (Object)v);
}
}
rb.rsp.add("facet_counts", counts);
}
}
自定義查詢元件
1、繼承SearchComponent
2、重寫實作prepare和process
@Override
public void prepare(final ResponseBuilder p0) throws IOException{
//TODO
};
@Override
public abstract void process(final ResponseBuilder p0) throws IOException{
//TODO
}
3、配置查詢元件
solrconfig.xml中的配置
将查詢元件配置到requestHandler下
<requestHandler name="/select" class="solr.SearchHandler">
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
<str name="df">text</str>
</lst>
<arr name="components">
<str>customer</str>
</arr>
</requestHandler>