Example usage for org.apache.lucene.search.grouping SearchGroup merge

List of usage examples for org.apache.lucene.search.grouping SearchGroup merge

Introduction

In this page you can find the example usage for org.apache.lucene.search.grouping SearchGroup merge.

Prototype

public static <T> Collection<SearchGroup<T>> merge(List<Collection<SearchGroup<T>>> topGroups, int offset,
        int topN, Sort groupSort) 

Source Link

Document

Merges multiple collections of top groups, for example obtained from separate index shards.

Usage

From source file:org.apache.solr.search.grouping.distributed.responseprocessor.SearchGroupShardResponseProcessor.java

License:Apache License

/**
 * {@inheritDoc}/*w  w  w  .ja  va  2  s . c  o m*/
 */
@Override
public void process(ResponseBuilder rb, ShardRequest shardRequest) {
    SortSpec ss = rb.getSortSpec();
    Sort groupSort = rb.getGroupingSpec().getGroupSort();
    String[] fields = rb.getGroupingSpec().getFields();

    Map<String, List<Collection<SearchGroup<BytesRef>>>> commandSearchGroups = new HashMap<String, List<Collection<SearchGroup<BytesRef>>>>();
    Map<String, Map<SearchGroup<BytesRef>, Set<String>>> tempSearchGroupToShards = new HashMap<String, Map<SearchGroup<BytesRef>, Set<String>>>();
    for (String field : fields) {
        commandSearchGroups.put(field,
                new ArrayList<Collection<SearchGroup<BytesRef>>>(shardRequest.responses.size()));
        tempSearchGroupToShards.put(field, new HashMap<SearchGroup<BytesRef>, Set<String>>());
        if (!rb.searchGroupToShards.containsKey(field)) {
            rb.searchGroupToShards.put(field, new HashMap<SearchGroup<BytesRef>, Set<String>>());
        }
    }

    SearchGroupsResultTransformer serializer = new SearchGroupsResultTransformer(rb.req.getSearcher());
    try {
        int maxElapsedTime = 0;
        int hitCountDuringFirstPhase = 0;

        NamedList<Object> shardInfo = null;
        if (rb.req.getParams().getBool(ShardParams.SHARDS_INFO, false)) {
            shardInfo = new SimpleOrderedMap<Object>();
            rb.rsp.getValues().add(ShardParams.SHARDS_INFO + ".firstPhase", shardInfo);
        }

        for (ShardResponse srsp : shardRequest.responses) {
            if (shardInfo != null) {
                SimpleOrderedMap<Object> nl = new SimpleOrderedMap<Object>();

                if (srsp.getException() != null) {
                    Throwable t = srsp.getException();
                    if (t instanceof SolrServerException) {
                        t = ((SolrServerException) t).getCause();
                    }
                    nl.add("error", t.toString());
                    StringWriter trace = new StringWriter();
                    t.printStackTrace(new PrintWriter(trace));
                    nl.add("trace", trace.toString());
                } else {
                    nl.add("numFound", (Integer) srsp.getSolrResponse().getResponse().get("totalHitCount"));
                }
                if (srsp.getSolrResponse() != null) {
                    nl.add("time", srsp.getSolrResponse().getElapsedTime());
                }

                shardInfo.add(srsp.getShard(), nl);
            }
            if (rb.req.getParams().getBool(ShardParams.SHARDS_TOLERANT, false) && srsp.getException() != null) {
                continue; // continue if there was an error and we're tolerant.  
            }
            maxElapsedTime = (int) Math.max(maxElapsedTime, srsp.getSolrResponse().getElapsedTime());
            @SuppressWarnings("unchecked")
            NamedList<NamedList> firstPhaseResult = (NamedList<NamedList>) srsp.getSolrResponse().getResponse()
                    .get("firstPhase");
            Map<String, Pair<Integer, Collection<SearchGroup<BytesRef>>>> result = serializer
                    .transformToNative(firstPhaseResult, groupSort, null, srsp.getShard());
            for (String field : commandSearchGroups.keySet()) {
                Pair<Integer, Collection<SearchGroup<BytesRef>>> firstPhaseCommandResult = result.get(field);
                Integer groupCount = firstPhaseCommandResult.getA();
                if (groupCount != null) {
                    Integer existingGroupCount = rb.mergedGroupCounts.get(field);
                    // Assuming groups don't cross shard boundary...
                    rb.mergedGroupCounts.put(field,
                            existingGroupCount != null ? existingGroupCount + groupCount : groupCount);
                }

                Collection<SearchGroup<BytesRef>> searchGroups = firstPhaseCommandResult.getB();
                if (searchGroups == null) {
                    continue;
                }

                commandSearchGroups.get(field).add(searchGroups);
                for (SearchGroup<BytesRef> searchGroup : searchGroups) {
                    Map<SearchGroup<BytesRef>, java.util.Set<String>> map = tempSearchGroupToShards.get(field);
                    Set<String> shards = map.get(searchGroup);
                    if (shards == null) {
                        shards = new HashSet<String>();
                        map.put(searchGroup, shards);
                    }
                    shards.add(srsp.getShard());
                }
            }
            hitCountDuringFirstPhase += (Integer) srsp.getSolrResponse().getResponse().get("totalHitCount");
        }
        rb.totalHitCount = hitCountDuringFirstPhase;
        rb.firstPhaseElapsedTime = maxElapsedTime;
        for (String groupField : commandSearchGroups.keySet()) {
            List<Collection<SearchGroup<BytesRef>>> topGroups = commandSearchGroups.get(groupField);
            Collection<SearchGroup<BytesRef>> mergedTopGroups = SearchGroup.merge(topGroups, ss.getOffset(),
                    ss.getCount(), groupSort);
            if (mergedTopGroups == null) {
                continue;
            }

            rb.mergedSearchGroups.put(groupField, mergedTopGroups);
            for (SearchGroup<BytesRef> mergedTopGroup : mergedTopGroups) {
                rb.searchGroupToShards.get(groupField).put(mergedTopGroup,
                        tempSearchGroupToShards.get(groupField).get(mergedTopGroup));
            }
        }
    } catch (IOException e) {
        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
    }
}