Java Code Examples for org.apache.lucene.search.grouping.GroupDocs

The following examples show how to use org.apache.lucene.search.grouping.GroupDocs. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: lucene-solr   Source File: Grouping.java    License: Apache License 2.0 6 votes vote down vote up
@Override
protected void finish() throws IOException {
  TopDocs topDocs = topCollector.topDocs();
  float maxScore;
  if (withinGroupSort == null || withinGroupSort.equals(Sort.RELEVANCE)) {
    maxScore = topDocs.scoreDocs.length == 0 ? Float.NaN : topDocs.scoreDocs[0].score;
  } else if (needScores) {
    // use top-level query to populate the scores
    TopFieldCollector.populateScores(topDocs.scoreDocs, searcher, Grouping.this.query);
    maxScore = maxScoreCollector.getMaxScore();
  } else {
    maxScore = Float.NaN;
  }
  
  GroupDocs<String> groupDocs = new GroupDocs<>(Float.NaN, maxScore, topDocs.totalHits, topDocs.scoreDocs, query.toString(), null);
  if (main) {
    mainResult = getDocList(groupDocs);
  } else {
    NamedList rsp = commonResponse();
    addDocList(rsp, groupDocs);
  }
}
 
Example 2
Source Project: lucene-solr   Source File: TopGroupsFieldCommand.java    License: Apache License 2.0 6 votes vote down vote up
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public void postCollect(IndexSearcher searcher) throws IOException {
  if (firstPhaseGroups.isEmpty()) {
    topGroups = new TopGroups<>(groupSort.getSort(), withinGroupSort.getSort(), 0, 0, new GroupDocs[0], Float.NaN);
    return;
  }

  FieldType fieldType = field.getType();
  if (fieldType.getNumberType() != null) {
    topGroups = GroupConverter.fromMutable(field, secondPassCollector.getTopGroups(0));
  } else {
    topGroups = secondPassCollector.getTopGroups(0);
  }
  if (needScores) {
    for (GroupDocs<?> group : topGroups.groups) {
      TopFieldCollector.populateScores(group.scoreDocs, searcher, query);
    }
  }
}
 
Example 3
Source Project: lucene-solr   Source File: GroupConverter.java    License: Apache License 2.0 6 votes vote down vote up
@SuppressWarnings({"unchecked", "rawtypes"})
static TopGroups<BytesRef> fromMutable(SchemaField field, TopGroups<MutableValue> values) {
  if (values == null) {
    return null;
  }
  
  FieldType fieldType = field.getType();

  GroupDocs<BytesRef> groupDocs[] = new GroupDocs[values.groups.length];

  for (int i = 0; i < values.groups.length; i++) {
    GroupDocs<MutableValue> original = values.groups[i];
    final BytesRef groupValue;
    if (original.groupValue.exists) {
      BytesRefBuilder binary = new BytesRefBuilder();
      fieldType.readableToIndexed(Utils.OBJECT_TO_STRING.apply(original.groupValue.toObject()), binary);
      groupValue = binary.get();
    } else {
      groupValue = null;
    }
    groupDocs[i] = new GroupDocs<>(original.score, original.maxScore, original.totalHits, original.scoreDocs, groupValue, original.groupSortValues);
  }
  
  return new TopGroups<>(values.groupSort, values.withinGroupSort, values.totalHitCount, values.totalGroupedHitCount, groupDocs, values.maxScore);
}
 
Example 4
Source Project: marathonv5   Source File: IndexSearcher.java    License: Apache License 2.0 5 votes vote down vote up
public Map<DocumentType, List<SearchResult>> search(String searchString) throws ParseException {
    Map<DocumentType, List<SearchResult>> resultMap = new TreeMap<DocumentType, List<SearchResult>>();
    try {
        Query query = parser.parse(searchString);
        final SecondPassGroupingCollector collector = new SecondPassGroupingCollector("documentType", searchGroups,
                Sort.RELEVANCE, null, 5, true, false, true);
        searcher.search(query, collector);
        final TopGroups groups = collector.getTopGroups(0);
        for (GroupDocs groupDocs : groups.groups) {
            DocumentType docType = DocumentType.valueOf(groupDocs.groupValue);
            List<SearchResult> results = new ArrayList<SearchResult>();
            for (ScoreDoc scoreDoc : groupDocs.scoreDocs) {
                Document doc = searcher.doc(scoreDoc.doc);
                SearchResult result = new SearchResult(
                        docType,
                        doc.get("name"),
                        doc.get("url"),
                        doc.get("className"),
                        doc.get("package"),
                        doc.get("ensemblePath"),
                        doc.get("shortDescription")
                );
                results.add(result);
            }
            resultMap.put(docType, results);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return resultMap;
}
 
Example 5
Source Project: marathonv5   Source File: IndexSearcher.java    License: Apache License 2.0 5 votes vote down vote up
public Map<DocumentType, List<SearchResult>> search(String searchString) throws ParseException {
    Map<DocumentType, List<SearchResult>> resultMap = new TreeMap<DocumentType, List<SearchResult>>();
    try {
        Query query = parser.parse(searchString);
        final SecondPassGroupingCollector collector = new SecondPassGroupingCollector("documentType", searchGroups,
                Sort.RELEVANCE, null, 5, true, false, true);
        searcher.search(query, collector);
        final TopGroups groups = collector.getTopGroups(0);
        for (GroupDocs groupDocs : groups.groups) {
            DocumentType docType = DocumentType.valueOf(groupDocs.groupValue);
            List<SearchResult> results = new ArrayList<SearchResult>();
            for (ScoreDoc scoreDoc : groupDocs.scoreDocs) {
                Document doc = searcher.doc(scoreDoc.doc);
                SearchResult result = new SearchResult(
                        docType,
                        doc.get("name"),
                        doc.get("url"),
                        doc.get("className"),
                        doc.get("package"),
                        doc.get("ensemblePath"),
                        doc.get("shortDescription")
                );
                results.add(result);
            }
            resultMap.put(docType, results);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return resultMap;
}
 
Example 6
Source Project: linden   Source File: LindenResultParser.java    License: Apache License 2.0 5 votes vote down vote up
public LindenResult parse(TopDocs topDocs, TopGroups<TopDocs> topGroupedDocs,
                          Facets facets, FacetsCollector facetsCollector) throws IOException {
  LindenResult result = new LindenResult();
  List<LindenHit> lindenHits;
  int totalHits = 0;
  if (topDocs != null) {
    totalHits = topDocs.totalHits;
    lindenHits = parseLindenHits(topDocs.scoreDocs);
  } else if (topGroupedDocs != null) {
    lindenHits = new ArrayList<>();
    totalHits = topGroupedDocs.totalHitCount;
    for (GroupDocs<TopDocs> group : topGroupedDocs.groups) {
      List<LindenHit> groupHits = parseLindenHits(group.scoreDocs);
      LindenHit hitGroup = new LindenHit(groupHits.get(0)).setGroupHits(groupHits);
      String groupField = request.getGroupParam().getGroupField();
      String groupValue = LindenUtil.getFieldStringValue(leaves, group.scoreDocs[0].doc, groupField);
      if (!hitGroup.isSetFields()) {
        hitGroup.setFields(new HashMap<String, String>());
      }
      hitGroup.getFields().put(groupField, groupValue);
      lindenHits.add(hitGroup);
    }
    int groupTotal = topGroupedDocs.totalGroupCount == null ? 0 : topGroupedDocs.totalGroupCount;
    result.setTotalGroups(groupTotal);
    result.setTotalGroupHits(topGroupedDocs.totalGroupedHitCount);
  } else {
    lindenHits = new ArrayList<>();
  }
  result.setTotalHits(totalHits);
  result.setHits(lindenHits);
  parseFacets(result, facets, facetsCollector);
  result.setQueryInfo(new QueryInfo().setQuery(query.toString()));
  if (filter != null) {
    result.getQueryInfo().setFilter(filter.toString());
  }
  if (sort != null) {
    result.getQueryInfo().setSort(sort.toString());
  }
  return result;
}
 
Example 7
Source Project: lucene-solr   Source File: Grouping.java    License: Apache License 2.0 5 votes vote down vote up
protected void populateScoresIfNecessary() throws IOException {
  if (needScores) {
    for (GroupDocs<?> groups : result.groups) {
      TopFieldCollector.populateScores(groups.scoreDocs, searcher, query);
    }
  }
}
 
Example 8
Source Project: lucene-solr   Source File: Grouping.java    License: Apache License 2.0 5 votes vote down vote up
protected DocList getDocList(@SuppressWarnings({"rawtypes"})GroupDocs groups) {
  assert groups.totalHits.relation == TotalHits.Relation.EQUAL_TO;
  int max = Math.toIntExact(groups.totalHits.value);
  int off = groupOffset;
  int len = docsPerGroup;
  if (format == Format.simple) {
    off = offset;
    len = numGroups;
  }
  int docsToCollect = getMax(off, len, max);

  // TODO: implement a DocList impl that doesn't need to start at offset=0
  int docsCollected = Math.min(docsToCollect, groups.scoreDocs.length);

  int ids[] = new int[docsCollected];
  float[] scores = needScores ? new float[docsCollected] : null;
  for (int i = 0; i < ids.length; i++) {
    ids[i] = groups.scoreDocs[i].doc;
    if (scores != null)
      scores[i] = groups.scoreDocs[i].score;
  }

  float score = groups.maxScore;
  maxScore = maxAvoidNaN(score, maxScore);
  DocSlice docs = new DocSlice(off, Math.max(0, ids.length - off), ids, scores, groups.totalHits.value, score, TotalHits.Relation.EQUAL_TO);

  if (getDocList) {
    DocIterator iter = docs.iterator();
    while (iter.hasNext())
      idSet.add(iter.nextDoc());
  }
  return docs;
}
 
Example 9
Source Project: lucene-solr   Source File: Grouping.java    License: Apache License 2.0 5 votes vote down vote up
protected DocList createSimpleResponse() {
  @SuppressWarnings({"rawtypes"})
  GroupDocs[] groups = result != null ? result.groups : new GroupDocs[0];

  List<Integer> ids = new ArrayList<>();
  List<Float> scores = new ArrayList<>();
  int docsToGather = getMax(offset, numGroups, maxDoc);
  int docsGathered = 0;
  float maxScore = Float.NaN;

  outer:
  for (@SuppressWarnings({"rawtypes"})GroupDocs group : groups) {
    maxScore = maxAvoidNaN(maxScore, group.maxScore);

    for (ScoreDoc scoreDoc : group.scoreDocs) {
      if (docsGathered >= docsToGather) {
        break outer;
      }

      ids.add(scoreDoc.doc);
      scores.add(scoreDoc.score);
      docsGathered++;
    }
  }

  int len = docsGathered > offset ? docsGathered - offset : 0;
  int[] docs = ArrayUtils.toPrimitive(ids.toArray(new Integer[ids.size()]));
  float[] docScores = ArrayUtils.toPrimitive(scores.toArray(new Float[scores.size()]));
  DocSlice docSlice = new DocSlice(offset, len, docs, docScores, getMatches(), maxScore, TotalHits.Relation.EQUAL_TO);

  if (getDocList) {
    for (int i = offset; i < docs.length; i++) {
      idSet.add(docs[i]);
    }
  }

  return docSlice;
}
 
Example 10
Source Project: lucene-solr   Source File: Grouping.java    License: Apache License 2.0 5 votes vote down vote up
@Override
@SuppressWarnings({"unchecked"})
protected void finish() throws IOException {
  if (secondPass != null) {
    result = secondPass.getTopGroups(0);
    populateScoresIfNecessary();
  }
  if (main) {
    mainResult = createSimpleResponse();
    return;
  }

  @SuppressWarnings({"rawtypes"})
  NamedList groupResult = commonResponse();

  if (format == Format.simple) {
    groupResult.add("doclist", createSimpleResponse());
    return;
  }

  @SuppressWarnings({"rawtypes"})
  List groupList = new ArrayList();
  groupResult.add("groups", groupList);        // grouped={ key={ groups=[

  if (result == null) {
    return;
  }

  // handle case of rows=0
  if (numGroups == 0) return;

  for (GroupDocs<MutableValue> group : result.groups) {
    @SuppressWarnings({"rawtypes"})
    NamedList nl = new SimpleOrderedMap();
    groupList.add(nl);                         // grouped={ key={ groups=[ {
    nl.add("groupValue", group.groupValue.toObject());
    addDocList(nl, group);
  }
}
 
Example 11
Source Project: lucene-solr   Source File: QueryComponent.java    License: Apache License 2.0 5 votes vote down vote up
@SuppressWarnings({"unchecked", "rawtypes"})
protected void groupedFinishStage(final ResponseBuilder rb) {
  // To have same response as non-distributed request.
  GroupingSpecification groupSpec = rb.getGroupingSpec();
  if (rb.mergedTopGroups.isEmpty()) {
    for (String field : groupSpec.getFields()) {
      rb.mergedTopGroups.put(field, new TopGroups(null, null, 0, 0, new GroupDocs[]{}, Float.NaN));
    }
    rb.resultIds = new HashMap<>();
  }

  EndResultTransformer.SolrDocumentSource solrDocumentSource = doc -> {
    ShardDoc solrDoc = (ShardDoc) doc;
    return rb.retrievedDocuments.get(solrDoc.id);
  };
  EndResultTransformer endResultTransformer;
  if (groupSpec.isMain()) {
    endResultTransformer = MAIN_END_RESULT_TRANSFORMER;
  } else if (Grouping.Format.grouped == groupSpec.getResponseFormat()) {
    endResultTransformer = new GroupedEndResultTransformer(rb.req.getSearcher());
  } else if (Grouping.Format.simple == groupSpec.getResponseFormat() && !groupSpec.isMain()) {
    endResultTransformer = SIMPLE_END_RESULT_TRANSFORMER;
  } else {
    return;
  }
  Map<String, Object> combinedMap = new LinkedHashMap<>();
  combinedMap.putAll(rb.mergedTopGroups);
  combinedMap.putAll(rb.mergedQueryCommandResults);
  endResultTransformer.transform(combinedMap, rb, solrDocumentSource);
}
 
Example 12
Source Project: lucene-solr   Source File: Grouping.java    License: Apache License 2.0 4 votes vote down vote up
@SuppressWarnings({"unchecked"})
protected void addDocList(@SuppressWarnings({"rawtypes"})NamedList rsp
        , @SuppressWarnings({"rawtypes"})GroupDocs groups) {
  rsp.add("doclist", getDocList(groups));
}
 
Example 13
Source Project: lucene-solr   Source File: Grouping.java    License: Apache License 2.0 4 votes vote down vote up
@Override
@SuppressWarnings({"unchecked"})
protected void finish() throws IOException {
  if (secondPass != null) {
    result = secondPass.getTopGroups(0);
    populateScoresIfNecessary();
  }
  if (main) {
    mainResult = createSimpleResponse();
    return;
  }

  @SuppressWarnings({"rawtypes"})
  NamedList groupResult = commonResponse();

  if (format == Format.simple) {
    groupResult.add("doclist", createSimpleResponse());
    return;
  }

  @SuppressWarnings({"rawtypes"})
  List groupList = new ArrayList();
  groupResult.add("groups", groupList);        // grouped={ key={ groups=[

  if (result == null) {
    return;
  }

  // handle case of rows=0
  if (numGroups == 0) return;

  for (GroupDocs<BytesRef> group : result.groups) {
    @SuppressWarnings({"rawtypes"})
    NamedList nl = new SimpleOrderedMap();
    groupList.add(nl);                         // grouped={ key={ groups=[ {


    // To keep the response format compatable with trunk.
    // In trunk MutableValue can convert an indexed value to its native type. E.g. string to int
    // The only option I currently see is the use the FieldType for this
    if (group.groupValue != null) {
      SchemaField schemaField = searcher.getSchema().getField(groupBy);
      FieldType fieldType = schemaField.getType();
      // use createFields so that fields having doc values are also supported
      // TODO: currently, this path is called only for string field, so
      // should we just use fieldType.toObject(schemaField, group.groupValue) here?
      List<IndexableField> fields = schemaField.createFields(group.groupValue.utf8ToString());
      if (CollectionUtils.isNotEmpty(fields)) {
        nl.add("groupValue", fieldType.toObject(fields.get(0)));
      } else {
        throw new SolrException(ErrorCode.INVALID_STATE,
            "Couldn't create schema field for grouping, group value: " + group.groupValue.utf8ToString()
            + ", field: " + schemaField);
      }
    } else {
      nl.add("groupValue", null);
    }

    addDocList(nl, group);
  }
}
 
Example 14
@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);
    
    // we need to ensure the uniqueField is included for collating docs with their return fields
    if (! rb.rsp.getReturnFields().wantsField(uniqueField.getName())) {
      // the user didn't ask for it, so we have to...
      sreq.params.add(CommonParams.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;
}