Search in sources :

Example 1 with FacetGroup

use of io.zulia.message.ZuliaQuery.FacetGroup in project zuliasearch by zuliaio.

the class FacetCombiner method getCombinedFacetGroup.

public FacetGroup getCombinedFacetGroup() {
    if (facetGroups.size() == 1) {
        return facetGroups.get(0).getFacetGroup();
    } else {
        Map<String, AtomicLong> facetCounts = new HashMap<>();
        Map<String, FixedBitSet> shardsReturned = new HashMap<>();
        FixedBitSet fullResults = new FixedBitSet(shardReponses);
        long[] minForShard = new long[shardReponses];
        for (FacetGroupWithShardIndex facetGroupWithShardIndex : facetGroups) {
            FacetGroup fg = facetGroupWithShardIndex.getFacetGroup();
            int shardIndex = facetGroupWithShardIndex.getShardIndex();
            for (FacetCount fc : fg.getFacetCountList()) {
                String facet = fc.getFacet();
                AtomicLong facetSum = facetCounts.get(facet);
                FixedBitSet shardSet = shardsReturned.get(facet);
                if (facetSum == null) {
                    facetSum = new AtomicLong();
                    facetCounts.put(facet, facetSum);
                    shardSet = new FixedBitSet(shardReponses);
                    shardsReturned.put(facet, shardSet);
                }
                long count = fc.getCount();
                facetSum.addAndGet(count);
                shardSet.set(shardIndex);
                minForShard[shardIndex] = count;
            }
            int shardFacets = countRequest.getShardFacets();
            int facetCountCount = fg.getFacetCountCount();
            if (facetCountCount < shardFacets || (shardFacets == -1)) {
                fullResults.set(shardIndex);
                minForShard[shardIndex] = 0;
            }
        }
        FacetGroup.Builder fg = FacetGroup.newBuilder();
        fg.setCountRequest(countRequest);
        int numberOfShards = shardIndexes.length;
        long maxValuePossibleMissing = 0;
        for (int i = 0; i < numberOfShards; i++) {
            maxValuePossibleMissing += minForShard[i];
        }
        boolean computeError = countRequest.getMaxFacets() > 0 && countRequest.getShardFacets() > 0 && numberOfShards > 1;
        boolean computePossibleMissing = computeError && (maxValuePossibleMissing != 0);
        SortedSet<FacetCountResult> sortedFacetResults = facetCounts.keySet().stream().map(facet -> new FacetCountResult(facet, facetCounts.get(facet).get())).collect(Collectors.toCollection(TreeSet::new));
        int maxCount = countRequest.getMaxFacets();
        long minCountReturned = 0;
        int count = 0;
        for (FacetCountResult facet : sortedFacetResults) {
            FixedBitSet shardCount = shardsReturned.get(facet.getFacet());
            shardCount.or(fullResults);
            FacetCount.Builder facetCountBuilder = FacetCount.newBuilder().setFacet(facet.getFacet()).setCount(facet.getCount());
            long maxWithError = 0;
            if (computeError) {
                long maxError = 0;
                if (shardCount.cardinality() < numberOfShards) {
                    for (int i = 0; i < numberOfShards; i++) {
                        if (!shardCount.get(i)) {
                            maxError += minForShard[i];
                        }
                    }
                }
                facetCountBuilder.setMaxError(maxError);
                maxWithError = maxError + facet.getCount();
            }
            count++;
            if (maxCount > 0 && count > maxCount) {
                if (computePossibleMissing) {
                    if (maxWithError > maxValuePossibleMissing) {
                        maxValuePossibleMissing = maxWithError;
                    }
                } else {
                    break;
                }
            } else {
                fg.addFacetCount(facetCountBuilder);
                minCountReturned = facet.getCount();
            }
        }
        if (!sortedFacetResults.isEmpty()) {
            if (maxValuePossibleMissing > minCountReturned) {
                fg.setPossibleMissing(true);
                fg.setMaxValuePossibleMissing(maxValuePossibleMissing);
            }
        }
        return fg.build();
    }
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) SortedSet(java.util.SortedSet) FacetCount(io.zulia.message.ZuliaQuery.FacetCount) Map(java.util.Map) ZuliaQuery(io.zulia.message.ZuliaQuery) FixedBitSet(org.apache.lucene.util.FixedBitSet) HashMap(java.util.HashMap) FacetGroup(io.zulia.message.ZuliaQuery.FacetGroup) Collectors(java.util.stream.Collectors) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) HashMap(java.util.HashMap) AtomicLong(java.util.concurrent.atomic.AtomicLong) FacetGroup(io.zulia.message.ZuliaQuery.FacetGroup) FixedBitSet(org.apache.lucene.util.FixedBitSet) FacetCount(io.zulia.message.ZuliaQuery.FacetCount)

Example 2 with FacetGroup

use of io.zulia.message.ZuliaQuery.FacetGroup in project zuliasearch by zuliaio.

the class QueryCombiner method getQueryResponse.

public QueryResponse getQueryResponse() throws Exception {
    validate();
    long totalHits = 0;
    long returnedHits = 0;
    for (ShardQueryResponse sr : shardResponses) {
        totalHits += sr.getTotalHits();
        returnedHits += sr.getScoredResultList().size();
    }
    QueryResponse.Builder builder = QueryResponse.newBuilder();
    builder.setTotalHits(totalHits);
    int resultsSize = Math.min(amount, (int) returnedHits);
    Map<CountRequest, FacetCombiner> facetCombinerMap = new HashMap<>();
    Map<StatRequest, StatCombiner> statCombinerMap = new HashMap<>();
    Map<AnalysisRequest, Map<String, Term.Builder>> analysisRequestToTermMap = new HashMap<>();
    int shardIndex = 0;
    for (ShardQueryResponse sr : shardResponses) {
        for (FacetGroup fg : sr.getFacetGroupList()) {
            CountRequest countRequest = fg.getCountRequest();
            FacetCombiner facetCombiner = facetCombinerMap.computeIfAbsent(countRequest, countRequest1 -> new FacetCombiner(countRequest, shardResponses.size()));
            facetCombiner.handleFacetGroupForShard(fg, shardIndex);
        }
        for (ZuliaQuery.StatGroup sg : sr.getStatGroupList()) {
            StatRequest statRequest = sg.getStatRequest();
            StatCombiner statCombiner = statCombinerMap.computeIfAbsent(statRequest, statRequest1 -> new StatCombiner(statRequest, shardResponses.size()));
            statCombiner.handleStatGroupForShard(sg, shardIndex);
        }
        for (AnalysisResult analysisResult : sr.getAnalysisResultList()) {
            AnalysisRequest analysisRequest = analysisResult.getAnalysisRequest();
            if (!analysisRequestToTermMap.containsKey(analysisRequest)) {
                analysisRequestToTermMap.put(analysisRequest, new HashMap<>());
            }
            Map<String, Term.Builder> termMap = analysisRequestToTermMap.get(analysisRequest);
            for (Term term : analysisResult.getTermsList()) {
                String key = term.getValue();
                if (!termMap.containsKey(key)) {
                    termMap.put(key, Term.newBuilder().setValue(key).setDocFreq(0).setTermFreq(0));
                }
                Term.Builder termsBuilder = termMap.get(key);
                termsBuilder.setDocFreq(termsBuilder.getDocFreq() + term.getDocFreq());
                termsBuilder.setScore(termsBuilder.getScore() + term.getScore());
                termsBuilder.setTermFreq(termsBuilder.getTermFreq() + term.getTermFreq());
            }
        }
        shardIndex++;
    }
    for (AnalysisRequest analysisRequest : analysisRequestList) {
        Map<String, Term.Builder> termMap = analysisRequestToTermMap.get(analysisRequest);
        if (termMap != null) {
            List<Term.Builder> terms = new ArrayList<>(termMap.values());
            List<Term.Builder> topTerms = TermFreq.getTopTerms(terms, analysisRequest.getTopN(), analysisRequest.getTermSort());
            AnalysisResult.Builder analysisResultBuilder = AnalysisResult.newBuilder().setAnalysisRequest(analysisRequest);
            topTerms.forEach(analysisResultBuilder::addTerms);
            builder.addAnalysisResult(analysisResultBuilder);
        }
    }
    for (FacetCombiner facetCombiner : facetCombinerMap.values()) {
        builder.addFacetGroup(facetCombiner.getCombinedFacetGroup());
    }
    for (StatCombiner statCombiner : statCombinerMap.values()) {
        builder.addStatGroup(statCombiner.getCombinedStatGroup());
    }
    Map<String, ScoredResult[]> lastIndexResultMap = createLastIndexResultMapWithPreviousLastResults();
    List<ScoredResult> results;
    if (shardResponses.size() > 1) {
        results = mergeResults((int) returnedHits, resultsSize, lastIndexResultMap);
    } else {
        ShardQueryResponse shardQueryResponse = shardResponses.get(0);
        results = shardQueryResponse.getScoredResultList();
        if (!results.isEmpty()) {
            lastIndexResultMap.get(shardQueryResponse.getIndexName())[shardQueryResponse.getShardNumber()] = results.get(results.size() - 1);
        }
    }
    if (start == 0) {
        builder.addAllResults(results);
    } else {
        int i = 0;
        for (ScoredResult scoredResult : results) {
            if (i >= start) {
                builder.addResults(scoredResult);
            }
            i++;
        }
    }
    builder.setLastResult(createLastResult(lastIndexResultMap));
    return builder.build();
}
Also used : AnalysisRequest(io.zulia.message.ZuliaQuery.AnalysisRequest) HashMap(java.util.HashMap) ZuliaQuery(io.zulia.message.ZuliaQuery) ArrayList(java.util.ArrayList) CountRequest(io.zulia.message.ZuliaQuery.CountRequest) StatRequest(io.zulia.message.ZuliaQuery.StatRequest) FacetGroup(io.zulia.message.ZuliaQuery.FacetGroup) ShardQueryResponse(io.zulia.message.ZuliaQuery.ShardQueryResponse) Term(io.zulia.message.ZuliaBase.Term) AnalysisResult(io.zulia.message.ZuliaQuery.AnalysisResult) QueryResponse(io.zulia.message.ZuliaServiceOuterClass.QueryResponse) ShardQueryResponse(io.zulia.message.ZuliaQuery.ShardQueryResponse) InternalQueryResponse(io.zulia.message.ZuliaServiceOuterClass.InternalQueryResponse) ScoredResult(io.zulia.message.ZuliaQuery.ScoredResult) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

ZuliaQuery (io.zulia.message.ZuliaQuery)2 FacetGroup (io.zulia.message.ZuliaQuery.FacetGroup)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Term (io.zulia.message.ZuliaBase.Term)1 AnalysisRequest (io.zulia.message.ZuliaQuery.AnalysisRequest)1 AnalysisResult (io.zulia.message.ZuliaQuery.AnalysisResult)1 CountRequest (io.zulia.message.ZuliaQuery.CountRequest)1 FacetCount (io.zulia.message.ZuliaQuery.FacetCount)1 ScoredResult (io.zulia.message.ZuliaQuery.ScoredResult)1 ShardQueryResponse (io.zulia.message.ZuliaQuery.ShardQueryResponse)1 StatRequest (io.zulia.message.ZuliaQuery.StatRequest)1 InternalQueryResponse (io.zulia.message.ZuliaServiceOuterClass.InternalQueryResponse)1 QueryResponse (io.zulia.message.ZuliaServiceOuterClass.QueryResponse)1 List (java.util.List)1 SortedSet (java.util.SortedSet)1 TreeSet (java.util.TreeSet)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 Collectors (java.util.stream.Collectors)1