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

The following examples show how to use org.apache.lucene.search.grouping.GroupDocs. 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 File: Grouping.java    From lucene-solr with 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 File: TopGroupsFieldCommand.java    From lucene-solr with 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 File: GroupConverter.java    From lucene-solr with 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 File: IndexSearcher.java    From marathonv5 with 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 File: IndexSearcher.java    From marathonv5 with 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 File: LindenResultParser.java    From linden with 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 File: Grouping.java    From lucene-solr with 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 File: Grouping.java    From lucene-solr with 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 File: Grouping.java    From lucene-solr with 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 File: Grouping.java    From lucene-solr with 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 File: QueryComponent.java    From lucene-solr with 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 File: Grouping.java    From lucene-solr with 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 File: Grouping.java    From lucene-solr with 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
Source File: StoredFieldsShardRequestFactory.java    From lucene-solr with Apache License 2.0 4 votes vote down vote up
@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;
}