use of com.xiaomi.linden.thrift.common.LindenHit in project linden by XiaoMi.
the class ResultMerger method mergeGroupSearch.
private static LindenResult mergeGroupSearch(LindenSearchRequest lindenRequest, List<LindenResult> resultList) {
LindenResult mergedResult = resultList.get(0);
if (!mergedResult.isSetHits()) {
mergedResult.setHits(new ArrayList<LindenHit>());
}
String groupField = lindenRequest.getGroupParam().getGroupField();
int innerLimit = lindenRequest.getGroupParam().getGroupInnerLimit();
// traverse LindenResults from shards
for (int i = 1; i < resultList.size(); ++i) {
LindenResult subResult = resultList.get(i);
if (!subResult.isSetHits()) {
continue;
}
mergedResult.totalHits += subResult.totalHits;
mergedResult.totalGroups = Math.max(mergedResult.totalGroups, subResult.totalGroups);
mergedResult.totalGroupHits += subResult.totalGroupHits;
// traverse groups in waiting LindenResult
for (LindenHit subGroup : subResult.getHits()) {
String groupName = subGroup.getFields().get(groupField);
boolean isFound = false;
// find the group in the merged groupList
for (int j = 0; j < mergedResult.getHitsSize(); ++j) {
LindenHit mergedHit = mergedResult.getHits().get(j);
if (mergedHit.getFields().get(groupField).equals(groupName)) {
Iterable<LindenHit> groupIterable = Iterables.mergeSorted(ImmutableList.of(subGroup.getGroupHits(), mergedHit.getGroupHits()), new LindenHitCmp(null));
List<LindenHit> hits = Lists.newArrayList(Iterables.limit(groupIterable, innerLimit));
if (mergedHit.getScore() < subGroup.getScore()) {
mergedHit = subGroup;
}
mergedHit.setGroupHits(hits);
mergedResult.getHits().set(j, mergedHit);
isFound = true;
break;
}
}
if (!isFound) {
mergedResult.getHits().add(subGroup);
}
}
}
// sort the group by score
Ordering<LindenHit> ordering = new Ordering<LindenHit>() {
@Override
public int compare(@Nullable LindenHit left, @Nullable LindenHit right) {
return Double.compare(left.getScore(), right.getScore());
}
};
List<LindenHit> orderedHits = // offset -> offset+size groups
ordering.greatestOf(mergedResult.getHits(), mergedResult.getHitsSize());
int from = lindenRequest.getOffset();
int size = lindenRequest.getLength();
if (from < orderedHits.size()) {
List<LindenHit> subHits = orderedHits.subList(from, Math.min(from + size, orderedHits.size()));
mergedResult.setHits(subHits);
} else {
mergedResult.setHits(new ArrayList<LindenHit>());
}
return mergedResult;
}
use of com.xiaomi.linden.thrift.common.LindenHit in project linden by XiaoMi.
the class ResultMerger method merge.
public static LindenResult merge(final LindenSearchRequest lindenRequest, final List<LindenResult> resultList) {
if (resultList == null || resultList.isEmpty()) {
return EMPTY_RESULT;
}
Iterator<LindenResult> iterator = resultList.iterator();
int failureCount = 0;
LindenResult failedResult = null;
while (iterator.hasNext()) {
LindenResult result = iterator.next();
if (!result.isSuccess()) {
failureCount++;
failedResult = result;
iterator.remove();
}
}
if (resultList.isEmpty()) {
if (failureCount == 1) {
LOGGER.error("The shard failed for search request {}", lindenRequest.toString());
return failedResult;
}
LOGGER.error("All shards failed for search request {}", lindenRequest.toString());
return ALL_SHARDS_FAILED_RESULT;
}
LindenResult mergedResult;
if (lindenRequest.isSetGroupParam()) {
// merge results for grouping search
mergedResult = mergeGroupSearch(lindenRequest, resultList);
} else {
// merge results for normal searching
mergedResult = new LindenResult().setTotalHits(0).setQueryInfo(resultList.get(0).queryInfo);
List<List<LindenHit>> hits = new ArrayList<>();
for (LindenResult result : resultList) {
mergedResult.totalHits += result.getTotalHits();
hits.add(result.getHits());
}
// merge LindenHit
List<LindenSortField> sortFields = lindenRequest.isSetSort() ? lindenRequest.getSort().getFields() : null;
Iterable<LindenHit> mergedHits = Iterables.mergeSorted(hits, new LindenHitCmp(sortFields));
List<LindenHit> topNHits = Lists.newArrayList(mergedHits);
if (lindenRequest.getOffset() <= topNHits.size()) {
List<LindenHit> subHits = topNHits.subList(lindenRequest.getOffset(), Math.min(lindenRequest.getOffset() + lindenRequest.getLength(), topNHits.size()));
mergedResult.setHits(subHits);
} else {
mergedResult.setHits(new ArrayList<LindenHit>());
}
}
// Merge facet result
if (lindenRequest.isSetFacet()) {
mergeFacet(lindenRequest, resultList, mergedResult);
}
if (failureCount > 0) {
mergedResult.setError(failureCount + " shards failed.");
}
return mergedResult;
}
use of com.xiaomi.linden.thrift.common.LindenHit in project linden by XiaoMi.
the class LindenResultParser method parseLindenHits.
// parse ScoreDoc to LindenHit
private List<LindenHit> parseLindenHits(ScoreDoc[] hits) throws IOException {
List<LindenHit> lindenHits = new ArrayList<>();
String idFieldName = config.getSchema().getId();
for (ScoreDoc hit : hits) {
LindenHit lindenHit = new LindenHit();
if (Double.isNaN(hit.score)) {
// get score for cluster result merge
if (sortScoreFieldPos != -1) {
lindenHit.setScore(Double.valueOf(((FieldDoc) hit).fields[sortScoreFieldPos].toString()));
} else {
lindenHit.setScore(1);
}
} else {
lindenHit.setScore(hit.score);
}
String id = LindenUtil.getFieldStringValue(leaves, hit.doc, idFieldName);
lindenHit.setId(id);
lindenHit = this.parseSpatial(hit.doc, lindenHit);
lindenHit = this.parseSort(hit, lindenHit);
lindenHit = this.parseSource(hit.doc, lindenHit);
lindenHit = this.parseExplain(hit.doc, lindenHit);
lindenHits.add(lindenHit);
}
lindenHits = this.parseSnippets(lindenHits, hits);
return lindenHits;
}
use of com.xiaomi.linden.thrift.common.LindenHit in project linden by XiaoMi.
the class LindenResultParser method parse.
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;
}
Aggregations