Search in sources :

Example 1 with StatsCache

use of org.apache.solr.search.stats.StatsCache in project lucene-solr by apache.

the class SolrCore method initStatsCache.

private StatsCache initStatsCache() {
    final StatsCache cache;
    PluginInfo pluginInfo = solrConfig.getPluginInfo(StatsCache.class.getName());
    if (pluginInfo != null && pluginInfo.className != null && pluginInfo.className.length() > 0) {
        cache = createInitInstance(pluginInfo, StatsCache.class, null, LocalStatsCache.class.getName());
        log.debug("Using statsCache impl: " + cache.getClass().getName());
    } else {
        log.debug("Using default statsCache cache: " + LocalStatsCache.class.getName());
        cache = new LocalStatsCache();
    }
    return cache;
}
Also used : LocalStatsCache(org.apache.solr.search.stats.LocalStatsCache) StatsCache(org.apache.solr.search.stats.StatsCache) LocalStatsCache(org.apache.solr.search.stats.LocalStatsCache)

Example 2 with StatsCache

use of org.apache.solr.search.stats.StatsCache in project lucene-solr by apache.

the class QueryComponent method updateStats.

protected void updateStats(ResponseBuilder rb, ShardRequest sreq) {
    StatsCache cache = rb.req.getCore().getStatsCache();
    cache.mergeToGlobalStats(rb.req, sreq.responses);
}
Also used : StatsCache(org.apache.solr.search.stats.StatsCache)

Example 3 with StatsCache

use of org.apache.solr.search.stats.StatsCache in project lucene-solr by apache.

the class QueryComponent method createMainQuery.

protected void createMainQuery(ResponseBuilder rb) {
    ShardRequest sreq = new ShardRequest();
    sreq.purpose = ShardRequest.PURPOSE_GET_TOP_IDS;
    String keyFieldName = rb.req.getSchema().getUniqueKeyField().getName();
    // one-pass algorithm if only id and score fields are requested, but not if fl=score since that's the same as fl=*,score
    ReturnFields fields = rb.rsp.getReturnFields();
    // distrib.singlePass=true forces a one-pass query regardless of requested fields
    boolean distribSinglePass = rb.req.getParams().getBool(ShardParams.DISTRIB_SINGLE_PASS, false);
    if (distribSinglePass || (fields != null && fields.wantsField(keyFieldName) && fields.getRequestedFieldNames() != null && (!fields.hasPatternMatching() && Arrays.asList(keyFieldName, "score").containsAll(fields.getRequestedFieldNames())))) {
        sreq.purpose |= ShardRequest.PURPOSE_GET_FIELDS;
        rb.onePassDistributedQuery = true;
    }
    sreq.params = new ModifiableSolrParams(rb.req.getParams());
    // TODO: base on current params or original params?
    // don't pass through any shards param
    sreq.params.remove(ShardParams.SHARDS);
    // results from the start.
    if (rb.shards_start > -1) {
        // if the client set shards.start set this explicitly
        sreq.params.set(CommonParams.START, rb.shards_start);
    } else {
        sreq.params.set(CommonParams.START, "0");
    }
    // we could just specify that this is a shard request.
    if (rb.shards_rows > -1) {
        // if the client set shards.rows set this explicity
        sreq.params.set(CommonParams.ROWS, rb.shards_rows);
    } else {
        sreq.params.set(CommonParams.ROWS, rb.getSortSpec().getOffset() + rb.getSortSpec().getCount());
    }
    sreq.params.set(ResponseBuilder.FIELD_SORT_VALUES, "true");
    boolean shardQueryIncludeScore = (rb.getFieldFlags() & SolrIndexSearcher.GET_SCORES) != 0 || rb.getSortSpec().includesScore();
    StringBuilder additionalFL = new StringBuilder();
    boolean additionalAdded = false;
    if (distribSinglePass) {
        String[] fls = rb.req.getParams().getParams(CommonParams.FL);
        if (fls != null && fls.length > 0 && (fls.length != 1 || !fls[0].isEmpty())) {
            // If the outer request contains actual FL's use them...
            sreq.params.set(CommonParams.FL, fls);
            if (!fields.wantsField(keyFieldName)) {
                additionalAdded = addFL(additionalFL, keyFieldName, additionalAdded);
            }
        } else {
            // ... else we need to explicitly ask for all fields, because we are going to add
            // additional fields below
            sreq.params.set(CommonParams.FL, "*");
        }
        if (!fields.wantsScore() && shardQueryIncludeScore) {
            additionalAdded = addFL(additionalFL, "score", additionalAdded);
        }
    } else {
        // reset so that only unique key is requested in shard requests
        sreq.params.set(CommonParams.FL, rb.req.getSchema().getUniqueKeyField().getName());
        if (shardQueryIncludeScore) {
            additionalAdded = addFL(additionalFL, "score", additionalAdded);
        }
    }
    if (shardQueryIncludeScore) {
        StatsCache statsCache = rb.req.getCore().getStatsCache();
        statsCache.sendGlobalStats(rb, sreq);
    }
    if (additionalAdded)
        sreq.params.add(CommonParams.FL, additionalFL.toString());
    rb.addRequest(this, sreq);
}
Also used : StatsCache(org.apache.solr.search.stats.StatsCache) SolrReturnFields(org.apache.solr.search.SolrReturnFields) ReturnFields(org.apache.solr.search.ReturnFields) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams)

Example 4 with StatsCache

use of org.apache.solr.search.stats.StatsCache in project lucene-solr by apache.

the class QueryComponent method process.

/**
   * Actually run the query
   */
@Override
public void process(ResponseBuilder rb) throws IOException {
    LOG.debug("process: {}", rb.req.getParams());
    SolrQueryRequest req = rb.req;
    SolrParams params = req.getParams();
    if (!params.getBool(COMPONENT_NAME, true)) {
        return;
    }
    SolrIndexSearcher searcher = req.getSearcher();
    StatsCache statsCache = req.getCore().getStatsCache();
    int purpose = params.getInt(ShardParams.SHARDS_PURPOSE, ShardRequest.PURPOSE_GET_TOP_IDS);
    if ((purpose & ShardRequest.PURPOSE_GET_TERM_STATS) != 0) {
        statsCache.returnLocalStats(rb, searcher);
        return;
    }
    // check if we need to update the local copy of global dfs
    if ((purpose & ShardRequest.PURPOSE_SET_TERM_STATS) != 0) {
        // retrieve from request and update local cache
        statsCache.receiveGlobalStats(req);
    }
    SolrQueryResponse rsp = rb.rsp;
    IndexSchema schema = searcher.getSchema();
    // Optional: This could also be implemented by the top-level searcher sending
    // a filter that lists the ids... that would be transparent to
    // the request handler, but would be more expensive (and would preserve score
    // too if desired).
    String ids = params.get(ShardParams.IDS);
    if (ids != null) {
        SchemaField idField = schema.getUniqueKeyField();
        List<String> idArr = StrUtils.splitSmart(ids, ",", true);
        int[] luceneIds = new int[idArr.size()];
        int docs = 0;
        if (idField.getType().isPointField()) {
            for (int i = 0; i < idArr.size(); i++) {
                int id = searcher.search(idField.getType().getFieldQuery(null, idField, idArr.get(i)), 1).scoreDocs[0].doc;
                if (id >= 0) {
                    luceneIds[docs++] = id;
                }
            }
        } else {
            for (int i = 0; i < idArr.size(); i++) {
                int id = searcher.getFirstMatch(new Term(idField.getName(), idField.getType().toInternal(idArr.get(i))));
                if (id >= 0)
                    luceneIds[docs++] = id;
            }
        }
        DocListAndSet res = new DocListAndSet();
        res.docList = new DocSlice(0, docs, luceneIds, null, docs, 0);
        if (rb.isNeedDocSet()) {
            // TODO: create a cache for this!
            List<Query> queries = new ArrayList<>();
            queries.add(rb.getQuery());
            List<Query> filters = rb.getFilters();
            if (filters != null)
                queries.addAll(filters);
            res.docSet = searcher.getDocSet(queries);
        }
        rb.setResults(res);
        ResultContext ctx = new BasicResultContext(rb);
        rsp.addResponse(ctx);
        return;
    }
    // -1 as flag if not set.
    long timeAllowed = params.getLong(CommonParams.TIME_ALLOWED, -1L);
    if (null != rb.getCursorMark() && 0 < timeAllowed) {
        // fundamentally incompatible
        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Can not search using both " + CursorMarkParams.CURSOR_MARK_PARAM + " and " + CommonParams.TIME_ALLOWED);
    }
    QueryCommand cmd = rb.getQueryCommand();
    cmd.setTimeAllowed(timeAllowed);
    req.getContext().put(SolrIndexSearcher.STATS_SOURCE, statsCache.get(req));
    QueryResult result = new QueryResult();
    cmd.setSegmentTerminateEarly(params.getBool(CommonParams.SEGMENT_TERMINATE_EARLY, CommonParams.SEGMENT_TERMINATE_EARLY_DEFAULT));
    if (cmd.getSegmentTerminateEarly()) {
        result.setSegmentTerminatedEarly(Boolean.FALSE);
    }
    //
    // grouping / field collapsing
    //
    GroupingSpecification groupingSpec = rb.getGroupingSpec();
    if (groupingSpec != null) {
        // not supported, silently ignore any segmentTerminateEarly flag
        cmd.setSegmentTerminateEarly(false);
        try {
            boolean needScores = (cmd.getFlags() & SolrIndexSearcher.GET_SCORES) != 0;
            if (params.getBool(GroupParams.GROUP_DISTRIBUTED_FIRST, false)) {
                CommandHandler.Builder topsGroupsActionBuilder = new CommandHandler.Builder().setQueryCommand(cmd).setNeedDocSet(// Order matters here
                false).setIncludeHitCount(true).setSearcher(searcher);
                for (String field : groupingSpec.getFields()) {
                    topsGroupsActionBuilder.addCommandField(new SearchGroupsFieldCommand.Builder().setField(schema.getField(field)).setGroupSort(groupingSpec.getGroupSort()).setTopNGroups(cmd.getOffset() + cmd.getLen()).setIncludeGroupCount(groupingSpec.isIncludeGroupCount()).build());
                }
                CommandHandler commandHandler = topsGroupsActionBuilder.build();
                commandHandler.execute();
                SearchGroupsResultTransformer serializer = new SearchGroupsResultTransformer(searcher);
                rsp.add("firstPhase", commandHandler.processResult(result, serializer));
                rsp.add("totalHitCount", commandHandler.getTotalHitCount());
                rb.setResult(result);
                return;
            } else if (params.getBool(GroupParams.GROUP_DISTRIBUTED_SECOND, false)) {
                CommandHandler.Builder secondPhaseBuilder = new CommandHandler.Builder().setQueryCommand(cmd).setTruncateGroups(groupingSpec.isTruncateGroups() && groupingSpec.getFields().length > 0).setSearcher(searcher);
                int docsToCollect = Grouping.getMax(groupingSpec.getWithinGroupOffset(), groupingSpec.getWithinGroupLimit(), searcher.maxDoc());
                docsToCollect = Math.max(docsToCollect, 1);
                for (String field : groupingSpec.getFields()) {
                    SchemaField schemaField = schema.getField(field);
                    String[] topGroupsParam = params.getParams(GroupParams.GROUP_DISTRIBUTED_TOPGROUPS_PREFIX + field);
                    if (topGroupsParam == null) {
                        topGroupsParam = new String[0];
                    }
                    List<SearchGroup<BytesRef>> topGroups = new ArrayList<>(topGroupsParam.length);
                    for (String topGroup : topGroupsParam) {
                        SearchGroup<BytesRef> searchGroup = new SearchGroup<>();
                        if (!topGroup.equals(TopGroupsShardRequestFactory.GROUP_NULL_VALUE)) {
                            BytesRefBuilder builder = new BytesRefBuilder();
                            schemaField.getType().readableToIndexed(topGroup, builder);
                            searchGroup.groupValue = builder.get();
                        }
                        topGroups.add(searchGroup);
                    }
                    secondPhaseBuilder.addCommandField(new TopGroupsFieldCommand.Builder().setField(schemaField).setGroupSort(groupingSpec.getGroupSort()).setSortWithinGroup(groupingSpec.getSortWithinGroup()).setFirstPhaseGroups(topGroups).setMaxDocPerGroup(docsToCollect).setNeedScores(needScores).setNeedMaxScore(needScores).build());
                }
                for (String query : groupingSpec.getQueries()) {
                    secondPhaseBuilder.addCommandField(new Builder().setDocsToCollect(docsToCollect).setSort(groupingSpec.getGroupSort()).setQuery(query, rb.req).setDocSet(searcher).build());
                }
                CommandHandler commandHandler = secondPhaseBuilder.build();
                commandHandler.execute();
                TopGroupsResultTransformer serializer = new TopGroupsResultTransformer(rb);
                rsp.add("secondPhase", commandHandler.processResult(result, serializer));
                rb.setResult(result);
                return;
            }
            int maxDocsPercentageToCache = params.getInt(GroupParams.GROUP_CACHE_PERCENTAGE, 0);
            boolean cacheSecondPassSearch = maxDocsPercentageToCache >= 1 && maxDocsPercentageToCache <= 100;
            Grouping.TotalCount defaultTotalCount = groupingSpec.isIncludeGroupCount() ? Grouping.TotalCount.grouped : Grouping.TotalCount.ungrouped;
            // this is normally from "rows"
            int limitDefault = cmd.getLen();
            Grouping grouping = new Grouping(searcher, result, cmd, cacheSecondPassSearch, maxDocsPercentageToCache, groupingSpec.isMain());
            grouping.setGroupSort(groupingSpec.getGroupSort()).setWithinGroupSort(groupingSpec.getSortWithinGroup()).setDefaultFormat(groupingSpec.getResponseFormat()).setLimitDefault(limitDefault).setDefaultTotalCount(defaultTotalCount).setDocsPerGroupDefault(groupingSpec.getWithinGroupLimit()).setGroupOffsetDefault(groupingSpec.getWithinGroupOffset()).setGetGroupedDocSet(groupingSpec.isTruncateGroups());
            if (groupingSpec.getFields() != null) {
                for (String field : groupingSpec.getFields()) {
                    grouping.addFieldCommand(field, rb.req);
                }
            }
            if (groupingSpec.getFunctions() != null) {
                for (String groupByStr : groupingSpec.getFunctions()) {
                    grouping.addFunctionCommand(groupByStr, rb.req);
                }
            }
            if (groupingSpec.getQueries() != null) {
                for (String groupByStr : groupingSpec.getQueries()) {
                    grouping.addQueryCommand(groupByStr, rb.req);
                }
            }
            if (rb.isNeedDocList() || rb.isDebug()) {
                // we need a single list of the returned docs
                cmd.setFlags(SolrIndexSearcher.GET_DOCLIST);
            }
            grouping.execute();
            if (grouping.isSignalCacheWarning()) {
                rsp.add("cacheWarning", String.format(Locale.ROOT, "Cache limit of %d percent relative to maxdoc has exceeded. Please increase cache size or disable caching.", maxDocsPercentageToCache));
            }
            rb.setResult(result);
            if (grouping.mainResult != null) {
                ResultContext ctx = new BasicResultContext(rb, grouping.mainResult);
                rsp.addResponse(ctx);
                rsp.getToLog().add("hits", grouping.mainResult.matches());
            } else if (!grouping.getCommands().isEmpty()) {
                // Can never be empty since grouping.execute() checks for this.
                rsp.add("grouped", result.groupedResults);
                rsp.getToLog().add("hits", grouping.getCommands().get(0).getMatches());
            }
            return;
        } catch (SyntaxError e) {
            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
        }
    }
    // normal search result
    searcher.search(result, cmd);
    rb.setResult(result);
    ResultContext ctx = new BasicResultContext(rb);
    rsp.addResponse(ctx);
    rsp.getToLog().add("hits", rb.getResults().docList.matches());
    if (!rb.req.getParams().getBool(ShardParams.IS_SHARD, false)) {
        if (null != rb.getNextCursorMark()) {
            rb.rsp.add(CursorMarkParams.CURSOR_MARK_NEXT, rb.getNextCursorMark().getSerializedTotem());
        }
    }
    if (rb.mergeFieldHandler != null) {
        rb.mergeFieldHandler.handleMergeFields(rb, searcher);
    } else {
        doFieldSortValues(rb, searcher);
    }
    doPrefetch(rb);
}
Also used : BasicResultContext(org.apache.solr.response.BasicResultContext) ResultContext(org.apache.solr.response.ResultContext) Query(org.apache.lucene.search.Query) MatchNoDocsQuery(org.apache.lucene.search.MatchNoDocsQuery) RankQuery(org.apache.solr.search.RankQuery) DocListAndSet(org.apache.solr.search.DocListAndSet) BytesRefBuilder(org.apache.lucene.util.BytesRefBuilder) Builder(org.apache.solr.search.grouping.distributed.command.QueryCommand.Builder) ArrayList(java.util.ArrayList) CommandHandler(org.apache.solr.search.grouping.CommandHandler) DocSlice(org.apache.solr.search.DocSlice) BasicResultContext(org.apache.solr.response.BasicResultContext) StatsCache(org.apache.solr.search.stats.StatsCache) QueryResult(org.apache.solr.search.QueryResult) SyntaxError(org.apache.solr.search.SyntaxError) SolrDocumentList(org.apache.solr.common.SolrDocumentList) DocList(org.apache.solr.search.DocList) List(java.util.List) ArrayList(java.util.ArrayList) NamedList(org.apache.solr.common.util.NamedList) GroupingSpecification(org.apache.solr.search.grouping.GroupingSpecification) SearchGroupsResultTransformer(org.apache.solr.search.grouping.distributed.shardresultserializer.SearchGroupsResultTransformer) SolrException(org.apache.solr.common.SolrException) BytesRef(org.apache.lucene.util.BytesRef) SolrQueryResponse(org.apache.solr.response.SolrQueryResponse) BytesRefBuilder(org.apache.lucene.util.BytesRefBuilder) SearchGroup(org.apache.lucene.search.grouping.SearchGroup) Grouping(org.apache.solr.search.Grouping) SolrIndexSearcher(org.apache.solr.search.SolrIndexSearcher) Term(org.apache.lucene.index.Term) TopGroupsResultTransformer(org.apache.solr.search.grouping.distributed.shardresultserializer.TopGroupsResultTransformer) SchemaField(org.apache.solr.schema.SchemaField) SolrQueryRequest(org.apache.solr.request.SolrQueryRequest) SolrParams(org.apache.solr.common.params.SolrParams) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams) QueryCommand(org.apache.solr.search.QueryCommand) IndexSchema(org.apache.solr.schema.IndexSchema)

Aggregations

StatsCache (org.apache.solr.search.stats.StatsCache)4 ModifiableSolrParams (org.apache.solr.common.params.ModifiableSolrParams)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Term (org.apache.lucene.index.Term)1 MatchNoDocsQuery (org.apache.lucene.search.MatchNoDocsQuery)1 Query (org.apache.lucene.search.Query)1 SearchGroup (org.apache.lucene.search.grouping.SearchGroup)1 BytesRef (org.apache.lucene.util.BytesRef)1 BytesRefBuilder (org.apache.lucene.util.BytesRefBuilder)1 SolrDocumentList (org.apache.solr.common.SolrDocumentList)1 SolrException (org.apache.solr.common.SolrException)1 SolrParams (org.apache.solr.common.params.SolrParams)1 NamedList (org.apache.solr.common.util.NamedList)1 SolrQueryRequest (org.apache.solr.request.SolrQueryRequest)1 BasicResultContext (org.apache.solr.response.BasicResultContext)1 ResultContext (org.apache.solr.response.ResultContext)1 SolrQueryResponse (org.apache.solr.response.SolrQueryResponse)1 IndexSchema (org.apache.solr.schema.IndexSchema)1 SchemaField (org.apache.solr.schema.SchemaField)1