Search in sources :

Example 1 with LindenHit

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;
}
Also used : LindenResult(com.xiaomi.linden.thrift.common.LindenResult) LindenHit(com.xiaomi.linden.thrift.common.LindenHit) Ordering(com.google.common.collect.Ordering) Nullable(javax.annotation.Nullable)

Example 2 with LindenHit

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;
}
Also used : ArrayList(java.util.ArrayList) LindenSortField(com.xiaomi.linden.thrift.common.LindenSortField) LindenResult(com.xiaomi.linden.thrift.common.LindenResult) LindenHit(com.xiaomi.linden.thrift.common.LindenHit) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Example 3 with LindenHit

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;
}
Also used : FieldDoc(org.apache.lucene.search.FieldDoc) LindenHit(com.xiaomi.linden.thrift.common.LindenHit) ArrayList(java.util.ArrayList) ScoreDoc(org.apache.lucene.search.ScoreDoc)

Example 4 with LindenHit

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;
}
Also used : LindenResult(com.xiaomi.linden.thrift.common.LindenResult) HashMap(java.util.HashMap) LindenHit(com.xiaomi.linden.thrift.common.LindenHit) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) GroupDocs(org.apache.lucene.search.grouping.GroupDocs) QueryInfo(com.xiaomi.linden.thrift.common.QueryInfo)

Aggregations

LindenHit (com.xiaomi.linden.thrift.common.LindenHit)4 LindenResult (com.xiaomi.linden.thrift.common.LindenResult)3 ArrayList (java.util.ArrayList)3 List (java.util.List)2 ImmutableList (com.google.common.collect.ImmutableList)1 Ordering (com.google.common.collect.Ordering)1 LindenSortField (com.xiaomi.linden.thrift.common.LindenSortField)1 QueryInfo (com.xiaomi.linden.thrift.common.QueryInfo)1 HashMap (java.util.HashMap)1 Nullable (javax.annotation.Nullable)1 FieldDoc (org.apache.lucene.search.FieldDoc)1 ScoreDoc (org.apache.lucene.search.ScoreDoc)1 GroupDocs (org.apache.lucene.search.grouping.GroupDocs)1