PageRenderTime 24ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/solr/core/src/java/org/apache/solr/search/grouping/endresulttransformer/GroupedEndResultTransformer.java

http://github.com/apache/lucene-solr
Java | 131 lines | 102 code | 9 blank | 20 comment | 19 complexity | 5af562638d4288f7fb46b9b1f32c4abe MD5 | raw file
Possible License(s): LGPL-2.1, CPL-1.0, MPL-2.0-no-copyleft-exception, JSON, Apache-2.0, AGPL-1.0, GPL-2.0, GPL-3.0, MIT, BSD-3-Clause
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.solr.search.grouping.endresulttransformer;
  18. import java.util.ArrayList;
  19. import java.util.List;
  20. import java.util.Map;
  21. import org.apache.commons.collections.CollectionUtils;
  22. import org.apache.lucene.index.IndexableField;
  23. import org.apache.lucene.search.ScoreDoc;
  24. import org.apache.lucene.search.TopDocs;
  25. import org.apache.lucene.search.TotalHits;
  26. import org.apache.lucene.search.grouping.GroupDocs;
  27. import org.apache.lucene.search.grouping.TopGroups;
  28. import org.apache.lucene.util.BytesRef;
  29. import org.apache.solr.common.SolrDocument;
  30. import org.apache.solr.common.SolrDocumentList;
  31. import org.apache.solr.common.SolrException;
  32. import org.apache.solr.common.SolrException.ErrorCode;
  33. import org.apache.solr.common.util.NamedList;
  34. import org.apache.solr.common.util.SimpleOrderedMap;
  35. import org.apache.solr.handler.component.ResponseBuilder;
  36. import org.apache.solr.schema.FieldType;
  37. import org.apache.solr.schema.SchemaField;
  38. import org.apache.solr.search.SolrIndexSearcher;
  39. import org.apache.solr.search.SortSpec;
  40. import org.apache.solr.search.grouping.distributed.command.QueryCommandResult;
  41. /**
  42. * Implementation of {@link EndResultTransformer} that keeps each grouped result separate in the final response.
  43. */
  44. public class GroupedEndResultTransformer implements EndResultTransformer {
  45. private final SolrIndexSearcher searcher;
  46. public GroupedEndResultTransformer(SolrIndexSearcher searcher) {
  47. this.searcher = searcher;
  48. }
  49. @Override
  50. public void transform(Map<String, ?> result, ResponseBuilder rb, SolrDocumentSource solrDocumentSource) {
  51. NamedList<Object> commands = new SimpleOrderedMap<>();
  52. SortSpec withinGroupSortSpec = rb.getGroupingSpec().getWithinGroupSortSpec();
  53. for (Map.Entry<String, ?> entry : result.entrySet()) {
  54. Object value = entry.getValue();
  55. if (TopGroups.class.isInstance(value)) {
  56. @SuppressWarnings("unchecked")
  57. TopGroups<BytesRef> topGroups = (TopGroups<BytesRef>) value;
  58. NamedList<Object> command = new SimpleOrderedMap<>();
  59. command.add("matches", rb.totalHitCount);
  60. Integer totalGroupCount = rb.mergedGroupCounts.get(entry.getKey());
  61. if (totalGroupCount != null) {
  62. command.add("ngroups", totalGroupCount);
  63. }
  64. List<NamedList> groups = new ArrayList<>();
  65. SchemaField groupField = searcher.getSchema().getField(entry.getKey());
  66. FieldType groupFieldType = groupField.getType();
  67. for (GroupDocs<BytesRef> group : topGroups.groups) {
  68. SimpleOrderedMap<Object> groupResult = new SimpleOrderedMap<>();
  69. if (group.groupValue != null) {
  70. // use createFields so that fields having doc values are also supported
  71. List<IndexableField> fields = groupField.createFields(group.groupValue.utf8ToString());
  72. if (CollectionUtils.isNotEmpty(fields)) {
  73. groupResult.add("groupValue", groupFieldType.toObject(fields.get(0)));
  74. } else {
  75. throw new SolrException(ErrorCode.INVALID_STATE,
  76. "Couldn't create schema field for grouping, group value: " + group.groupValue.utf8ToString()
  77. + ", field: " + groupField);
  78. }
  79. } else {
  80. groupResult.add("groupValue", null);
  81. }
  82. SolrDocumentList docList = new SolrDocumentList();
  83. assert group.totalHits.relation == TotalHits.Relation.EQUAL_TO;
  84. docList.setNumFound(group.totalHits.value);
  85. if (!Float.isNaN(group.maxScore)) {
  86. docList.setMaxScore(group.maxScore);
  87. }
  88. docList.setStart(withinGroupSortSpec.getOffset());
  89. retrieveAndAdd(docList, solrDocumentSource, group.scoreDocs);
  90. groupResult.add("doclist", docList);
  91. groups.add(groupResult);
  92. }
  93. command.add("groups", groups);
  94. commands.add(entry.getKey(), command);
  95. } else if (QueryCommandResult.class.isInstance(value)) {
  96. QueryCommandResult queryCommandResult = (QueryCommandResult) value;
  97. NamedList<Object> command = new SimpleOrderedMap<>();
  98. command.add("matches", queryCommandResult.getMatches());
  99. SolrDocumentList docList = new SolrDocumentList();
  100. TopDocs topDocs = queryCommandResult.getTopDocs();
  101. assert topDocs.totalHits.relation == TotalHits.Relation.EQUAL_TO;
  102. docList.setNumFound(topDocs.totalHits.value);
  103. if (!Float.isNaN(queryCommandResult.getMaxScore())) {
  104. docList.setMaxScore(queryCommandResult.getMaxScore());
  105. }
  106. docList.setStart(withinGroupSortSpec.getOffset());
  107. retrieveAndAdd(docList, solrDocumentSource, queryCommandResult.getTopDocs().scoreDocs);
  108. command.add("doclist", docList);
  109. commands.add(entry.getKey(), command);
  110. }
  111. }
  112. rb.rsp.add("grouped", commands);
  113. }
  114. private static void retrieveAndAdd(SolrDocumentList solrDocumentList, SolrDocumentSource solrDocumentSource, ScoreDoc[] scoreDocs) {
  115. for (ScoreDoc scoreDoc : scoreDocs) {
  116. SolrDocument solrDocument = solrDocumentSource.retrieve(scoreDoc);
  117. if (solrDocument != null) {
  118. solrDocumentList.add(solrDocument);
  119. }
  120. }
  121. }
  122. }