Search in sources :

Example 1 with QueryCommandResult

use of org.apache.solr.search.grouping.distributed.command.QueryCommandResult in project lucene-solr by apache.

the class GroupedEndResultTransformer method transform.

/**
   * {@inheritDoc}
   */
@Override
public void transform(Map<String, ?> result, ResponseBuilder rb, SolrDocumentSource solrDocumentSource) {
    NamedList<Object> commands = new SimpleOrderedMap<>();
    for (Map.Entry<String, ?> entry : result.entrySet()) {
        Object value = entry.getValue();
        if (TopGroups.class.isInstance(value)) {
            @SuppressWarnings("unchecked") TopGroups<BytesRef> topGroups = (TopGroups<BytesRef>) value;
            NamedList<Object> command = new SimpleOrderedMap<>();
            command.add("matches", rb.totalHitCount);
            Integer totalGroupCount = rb.mergedGroupCounts.get(entry.getKey());
            if (totalGroupCount != null) {
                command.add("ngroups", totalGroupCount);
            }
            List<NamedList> groups = new ArrayList<>();
            SchemaField groupField = searcher.getSchema().getField(entry.getKey());
            FieldType groupFieldType = groupField.getType();
            for (GroupDocs<BytesRef> group : topGroups.groups) {
                SimpleOrderedMap<Object> groupResult = new SimpleOrderedMap<>();
                if (group.groupValue != null) {
                    groupResult.add("groupValue", groupFieldType.toObject(groupField.createField(group.groupValue.utf8ToString())));
                } else {
                    groupResult.add("groupValue", null);
                }
                SolrDocumentList docList = new SolrDocumentList();
                docList.setNumFound(group.totalHits);
                if (!Float.isNaN(group.maxScore)) {
                    docList.setMaxScore(group.maxScore);
                }
                docList.setStart(rb.getGroupingSpec().getWithinGroupOffset());
                for (ScoreDoc scoreDoc : group.scoreDocs) {
                    docList.add(solrDocumentSource.retrieve(scoreDoc));
                }
                groupResult.add("doclist", docList);
                groups.add(groupResult);
            }
            command.add("groups", groups);
            commands.add(entry.getKey(), command);
        } else if (QueryCommandResult.class.isInstance(value)) {
            QueryCommandResult queryCommandResult = (QueryCommandResult) value;
            NamedList<Object> command = new SimpleOrderedMap<>();
            command.add("matches", queryCommandResult.getMatches());
            SolrDocumentList docList = new SolrDocumentList();
            docList.setNumFound(queryCommandResult.getTopDocs().totalHits);
            if (!Float.isNaN(queryCommandResult.getTopDocs().getMaxScore())) {
                docList.setMaxScore(queryCommandResult.getTopDocs().getMaxScore());
            }
            docList.setStart(rb.getGroupingSpec().getWithinGroupOffset());
            for (ScoreDoc scoreDoc : queryCommandResult.getTopDocs().scoreDocs) {
                docList.add(solrDocumentSource.retrieve(scoreDoc));
            }
            command.add("doclist", docList);
            commands.add(entry.getKey(), command);
        }
    }
    rb.rsp.add("grouped", commands);
}
Also used : NamedList(org.apache.solr.common.util.NamedList) ArrayList(java.util.ArrayList) QueryCommandResult(org.apache.solr.search.grouping.distributed.command.QueryCommandResult) SolrDocumentList(org.apache.solr.common.SolrDocumentList) SimpleOrderedMap(org.apache.solr.common.util.SimpleOrderedMap) FieldType(org.apache.solr.schema.FieldType) ScoreDoc(org.apache.lucene.search.ScoreDoc) SchemaField(org.apache.solr.schema.SchemaField) TopGroups(org.apache.lucene.search.grouping.TopGroups) SimpleOrderedMap(org.apache.solr.common.util.SimpleOrderedMap) Map(java.util.Map) BytesRef(org.apache.lucene.util.BytesRef)

Example 2 with QueryCommandResult

use of org.apache.solr.search.grouping.distributed.command.QueryCommandResult in project lucene-solr by apache.

the class TopGroupsResultTransformer method transformToNative.

/**
   * {@inheritDoc}
   */
@Override
public Map<String, ?> transformToNative(NamedList<NamedList> shardResponse, Sort groupSort, Sort withinGroupSort, String shard) {
    Map<String, Object> result = new HashMap<>();
    final IndexSchema schema = rb.req.getSearcher().getSchema();
    for (Map.Entry<String, NamedList> entry : shardResponse) {
        String key = entry.getKey();
        NamedList commandResult = entry.getValue();
        Integer totalGroupedHitCount = (Integer) commandResult.get("totalGroupedHitCount");
        Integer totalHits = (Integer) commandResult.get("totalHits");
        if (totalHits != null) {
            Integer matches = (Integer) commandResult.get("matches");
            Float maxScore = (Float) commandResult.get("maxScore");
            if (maxScore == null) {
                maxScore = Float.NaN;
            }
            @SuppressWarnings("unchecked") List<NamedList<Object>> documents = (List<NamedList<Object>>) commandResult.get("documents");
            ScoreDoc[] scoreDocs = transformToNativeShardDoc(documents, groupSort, shard, schema);
            final TopDocs topDocs;
            if (withinGroupSort.equals(Sort.RELEVANCE)) {
                topDocs = new TopDocs(totalHits, scoreDocs, maxScore);
            } else {
                topDocs = new TopFieldDocs(totalHits, scoreDocs, withinGroupSort.getSort(), maxScore);
            }
            result.put(key, new QueryCommandResult(topDocs, matches));
            continue;
        }
        Integer totalHitCount = (Integer) commandResult.get("totalHitCount");
        List<GroupDocs<BytesRef>> groupDocs = new ArrayList<>();
        for (int i = 2; i < commandResult.size(); i++) {
            String groupValue = commandResult.getName(i);
            @SuppressWarnings("unchecked") NamedList<Object> groupResult = (NamedList<Object>) commandResult.getVal(i);
            Integer totalGroupHits = (Integer) groupResult.get("totalHits");
            Float maxScore = (Float) groupResult.get("maxScore");
            if (maxScore == null) {
                maxScore = Float.NaN;
            }
            @SuppressWarnings("unchecked") List<NamedList<Object>> documents = (List<NamedList<Object>>) groupResult.get("documents");
            ScoreDoc[] scoreDocs = transformToNativeShardDoc(documents, withinGroupSort, shard, schema);
            BytesRef groupValueRef = groupValue != null ? new BytesRef(groupValue) : null;
            groupDocs.add(new GroupDocs<>(Float.NaN, maxScore, totalGroupHits, scoreDocs, groupValueRef, null));
        }
        @SuppressWarnings("unchecked") GroupDocs<BytesRef>[] groupDocsArr = groupDocs.toArray(new GroupDocs[groupDocs.size()]);
        TopGroups<BytesRef> topGroups = new TopGroups<>(groupSort.getSort(), withinGroupSort.getSort(), totalHitCount, totalGroupedHitCount, groupDocsArr, Float.NaN);
        result.put(key, topGroups);
    }
    return result;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TopFieldDocs(org.apache.lucene.search.TopFieldDocs) ScoreDoc(org.apache.lucene.search.ScoreDoc) TopDocs(org.apache.lucene.search.TopDocs) ArrayList(java.util.ArrayList) NamedList(org.apache.solr.common.util.NamedList) List(java.util.List) TopGroups(org.apache.lucene.search.grouping.TopGroups) BytesRef(org.apache.lucene.util.BytesRef) NamedList(org.apache.solr.common.util.NamedList) QueryCommandResult(org.apache.solr.search.grouping.distributed.command.QueryCommandResult) IndexSchema(org.apache.solr.schema.IndexSchema) GroupDocs(org.apache.lucene.search.grouping.GroupDocs) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with QueryCommandResult

use of org.apache.solr.search.grouping.distributed.command.QueryCommandResult in project lucene-solr by apache.

the class StoredFieldsShardRequestFactory method constructRequest.

@Override
public ShardRequest[] constructRequest(ResponseBuilder rb) {
    HashMap<String, Set<ShardDoc>> shardMap = new HashMap<>();
    for (TopGroups<BytesRef> topGroups : rb.mergedTopGroups.values()) {
        for (GroupDocs<BytesRef> group : topGroups.groups) {
            mapShardToDocs(shardMap, group.scoreDocs);
        }
    }
    for (QueryCommandResult queryCommandResult : rb.mergedQueryCommandResults.values()) {
        mapShardToDocs(shardMap, queryCommandResult.getTopDocs().scoreDocs);
    }
    ShardRequest[] shardRequests = new ShardRequest[shardMap.size()];
    SchemaField uniqueField = rb.req.getSchema().getUniqueKeyField();
    int i = 0;
    for (Collection<ShardDoc> shardDocs : shardMap.values()) {
        ShardRequest sreq = new ShardRequest();
        sreq.purpose = ShardRequest.PURPOSE_GET_FIELDS;
        sreq.shards = new String[] { shardDocs.iterator().next().shard };
        sreq.params = new ModifiableSolrParams();
        sreq.params.add(rb.req.getParams());
        sreq.params.remove(GroupParams.GROUP);
        sreq.params.remove(CommonParams.SORT);
        sreq.params.remove(ResponseBuilder.FIELD_SORT_VALUES);
        String fl = sreq.params.get(CommonParams.FL);
        if (fl != null) {
            fl = fl.trim();
            // don't add "id" if the fl is empty or "score" or it would change the meaning.
            if (fl.length() != 0 && !"score".equals(fl) && !"*".equals(fl)) {
                sreq.params.set(CommonParams.FL, fl + ',' + uniqueField.getName());
            }
        }
        List<String> ids = new ArrayList<>(shardDocs.size());
        for (ShardDoc shardDoc : shardDocs) {
            ids.add(shardDoc.id.toString());
        }
        sreq.params.add(ShardParams.IDS, StrUtils.join(ids, ','));
        shardRequests[i++] = sreq;
    }
    return shardRequests;
}
Also used : QueryCommandResult(org.apache.solr.search.grouping.distributed.command.QueryCommandResult) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams) SchemaField(org.apache.solr.schema.SchemaField) ShardRequest(org.apache.solr.handler.component.ShardRequest) BytesRef(org.apache.lucene.util.BytesRef) ShardDoc(org.apache.solr.handler.component.ShardDoc)

Example 4 with QueryCommandResult

use of org.apache.solr.search.grouping.distributed.command.QueryCommandResult in project lucene-solr by apache.

the class TopGroupsShardResponseProcessor method process.

/**
   * {@inheritDoc}
   */
@Override
@SuppressWarnings("unchecked")
public void process(ResponseBuilder rb, ShardRequest shardRequest) {
    Sort groupSort = rb.getGroupingSpec().getGroupSort();
    String[] fields = rb.getGroupingSpec().getFields();
    String[] queries = rb.getGroupingSpec().getQueries();
    Sort withinGroupSort = rb.getGroupingSpec().getSortWithinGroup();
    assert withinGroupSort != null;
    // If group.format=simple group.offset doesn't make sense
    int groupOffsetDefault;
    if (rb.getGroupingSpec().getResponseFormat() == Grouping.Format.simple || rb.getGroupingSpec().isMain()) {
        groupOffsetDefault = 0;
    } else {
        groupOffsetDefault = rb.getGroupingSpec().getWithinGroupOffset();
    }
    int docsPerGroupDefault = rb.getGroupingSpec().getWithinGroupLimit();
    Map<String, List<TopGroups<BytesRef>>> commandTopGroups = new HashMap<>();
    for (String field : fields) {
        commandTopGroups.put(field, new ArrayList<TopGroups<BytesRef>>());
    }
    Map<String, List<QueryCommandResult>> commandTopDocs = new HashMap<>();
    for (String query : queries) {
        commandTopDocs.put(query, new ArrayList<QueryCommandResult>());
    }
    TopGroupsResultTransformer serializer = new TopGroupsResultTransformer(rb);
    NamedList<Object> shardInfo = null;
    if (rb.req.getParams().getBool(ShardParams.SHARDS_INFO, false)) {
        shardInfo = new SimpleOrderedMap<>();
        rb.rsp.getValues().add(ShardParams.SHARDS_INFO, shardInfo);
    }
    for (ShardResponse srsp : shardRequest.responses) {
        SimpleOrderedMap<Object> individualShardInfo = null;
        if (shardInfo != null) {
            individualShardInfo = new SimpleOrderedMap<>();
            if (srsp.getException() != null) {
                Throwable t = srsp.getException();
                if (t instanceof SolrServerException && ((SolrServerException) t).getCause() != null) {
                    t = ((SolrServerException) t).getCause();
                }
                individualShardInfo.add("error", t.toString());
                StringWriter trace = new StringWriter();
                t.printStackTrace(new PrintWriter(trace));
                individualShardInfo.add("trace", trace.toString());
            } else {
            // summary for successful shard response is added down below
            }
            if (srsp.getSolrResponse() != null) {
                individualShardInfo.add("time", srsp.getSolrResponse().getElapsedTime());
            }
            if (srsp.getShardAddress() != null) {
                individualShardInfo.add("shardAddress", srsp.getShardAddress());
            }
            shardInfo.add(srsp.getShard(), individualShardInfo);
        }
        if (rb.req.getParams().getBool(ShardParams.SHARDS_TOLERANT, false) && srsp.getException() != null) {
            if (rb.rsp.getResponseHeader().get(SolrQueryResponse.RESPONSE_HEADER_PARTIAL_RESULTS_KEY) == null) {
                rb.rsp.getResponseHeader().add(SolrQueryResponse.RESPONSE_HEADER_PARTIAL_RESULTS_KEY, Boolean.TRUE);
            }
            // continue if there was an error and we're tolerant.  
            continue;
        }
        NamedList<NamedList> secondPhaseResult = (NamedList<NamedList>) srsp.getSolrResponse().getResponse().get("secondPhase");
        if (secondPhaseResult == null)
            continue;
        Map<String, ?> result = serializer.transformToNative(secondPhaseResult, groupSort, withinGroupSort, srsp.getShard());
        int numFound = 0;
        float maxScore = Float.NaN;
        for (String field : commandTopGroups.keySet()) {
            TopGroups<BytesRef> topGroups = (TopGroups<BytesRef>) result.get(field);
            if (topGroups == null) {
                continue;
            }
            if (individualShardInfo != null) {
                // keep track of this when shards.info=true
                numFound += topGroups.totalHitCount;
                if (Float.isNaN(maxScore) || topGroups.maxScore > maxScore)
                    maxScore = topGroups.maxScore;
            }
            commandTopGroups.get(field).add(topGroups);
        }
        for (String query : queries) {
            QueryCommandResult queryCommandResult = (QueryCommandResult) result.get(query);
            if (individualShardInfo != null) {
                // keep track of this when shards.info=true
                numFound += queryCommandResult.getMatches();
                float thisMax = queryCommandResult.getTopDocs().getMaxScore();
                if (Float.isNaN(maxScore) || thisMax > maxScore)
                    maxScore = thisMax;
            }
            commandTopDocs.get(query).add(queryCommandResult);
        }
        if (individualShardInfo != null) {
            // when shards.info=true
            individualShardInfo.add("numFound", numFound);
            individualShardInfo.add("maxScore", maxScore);
        }
    }
    for (String groupField : commandTopGroups.keySet()) {
        List<TopGroups<BytesRef>> topGroups = commandTopGroups.get(groupField);
        if (topGroups.isEmpty()) {
            continue;
        }
        TopGroups<BytesRef>[] topGroupsArr = new TopGroups[topGroups.size()];
        int docsPerGroup = docsPerGroupDefault;
        if (docsPerGroup < 0) {
            docsPerGroup = 0;
            for (TopGroups subTopGroups : topGroups) {
                docsPerGroup += subTopGroups.totalGroupedHitCount;
            }
        }
        rb.mergedTopGroups.put(groupField, TopGroups.merge(topGroups.toArray(topGroupsArr), groupSort, withinGroupSort, groupOffsetDefault, docsPerGroup, TopGroups.ScoreMergeMode.None));
    }
    for (String query : commandTopDocs.keySet()) {
        List<QueryCommandResult> queryCommandResults = commandTopDocs.get(query);
        List<TopDocs> topDocs = new ArrayList<>(queryCommandResults.size());
        int mergedMatches = 0;
        for (QueryCommandResult queryCommandResult : queryCommandResults) {
            topDocs.add(queryCommandResult.getTopDocs());
            mergedMatches += queryCommandResult.getMatches();
        }
        int topN = rb.getGroupingSpec().getOffset() + rb.getGroupingSpec().getLimit();
        final TopDocs mergedTopDocs;
        if (withinGroupSort.equals(Sort.RELEVANCE)) {
            mergedTopDocs = TopDocs.merge(topN, topDocs.toArray(new TopDocs[topDocs.size()]));
        } else {
            mergedTopDocs = TopDocs.merge(withinGroupSort, topN, topDocs.toArray(new TopFieldDocs[topDocs.size()]));
        }
        rb.mergedQueryCommandResults.put(query, new QueryCommandResult(mergedTopDocs, mergedMatches));
    }
    Map<Object, ShardDoc> resultIds = new HashMap<>();
    int i = 0;
    for (TopGroups<BytesRef> topGroups : rb.mergedTopGroups.values()) {
        for (GroupDocs<BytesRef> group : topGroups.groups) {
            for (ScoreDoc scoreDoc : group.scoreDocs) {
                ShardDoc solrDoc = (ShardDoc) scoreDoc;
                // Include the first if there are duplicate IDs
                if (!resultIds.containsKey(solrDoc.id)) {
                    solrDoc.positionInResponse = i++;
                    resultIds.put(solrDoc.id, solrDoc);
                }
            }
        }
    }
    for (QueryCommandResult queryCommandResult : rb.mergedQueryCommandResults.values()) {
        for (ScoreDoc scoreDoc : queryCommandResult.getTopDocs().scoreDocs) {
            ShardDoc solrDoc = (ShardDoc) scoreDoc;
            solrDoc.positionInResponse = i++;
            resultIds.put(solrDoc.id, solrDoc);
        }
    }
    rb.resultIds = resultIds;
}
Also used : HashMap(java.util.HashMap) SolrServerException(org.apache.solr.client.solrj.SolrServerException) ArrayList(java.util.ArrayList) ScoreDoc(org.apache.lucene.search.ScoreDoc) ShardResponse(org.apache.solr.handler.component.ShardResponse) TopDocs(org.apache.lucene.search.TopDocs) StringWriter(java.io.StringWriter) Sort(org.apache.lucene.search.Sort) ArrayList(java.util.ArrayList) NamedList(org.apache.solr.common.util.NamedList) List(java.util.List) TopGroups(org.apache.lucene.search.grouping.TopGroups) BytesRef(org.apache.lucene.util.BytesRef) ShardDoc(org.apache.solr.handler.component.ShardDoc) PrintWriter(java.io.PrintWriter) NamedList(org.apache.solr.common.util.NamedList) QueryCommandResult(org.apache.solr.search.grouping.distributed.command.QueryCommandResult) TopGroupsResultTransformer(org.apache.solr.search.grouping.distributed.shardresultserializer.TopGroupsResultTransformer)

Aggregations

BytesRef (org.apache.lucene.util.BytesRef)4 QueryCommandResult (org.apache.solr.search.grouping.distributed.command.QueryCommandResult)4 ArrayList (java.util.ArrayList)3 ScoreDoc (org.apache.lucene.search.ScoreDoc)3 TopGroups (org.apache.lucene.search.grouping.TopGroups)3 NamedList (org.apache.solr.common.util.NamedList)3 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 TopDocs (org.apache.lucene.search.TopDocs)2 ShardDoc (org.apache.solr.handler.component.ShardDoc)2 SchemaField (org.apache.solr.schema.SchemaField)2 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 Sort (org.apache.lucene.search.Sort)1 TopFieldDocs (org.apache.lucene.search.TopFieldDocs)1 GroupDocs (org.apache.lucene.search.grouping.GroupDocs)1 SolrServerException (org.apache.solr.client.solrj.SolrServerException)1 SolrDocumentList (org.apache.solr.common.SolrDocumentList)1 ModifiableSolrParams (org.apache.solr.common.params.ModifiableSolrParams)1