Search in sources :

Example 1 with CursorMark

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

the class QueryComponent method populateNextCursorMarkFromMergedShards.

/**
   * Inspects the state of the {@link ResponseBuilder} and populates the next 
   * {@link ResponseBuilder#setNextCursorMark} as appropriate based on the merged 
   * sort values from individual shards
   *
   * @param rb A <code>ResponseBuilder</code> that already contains merged 
   *           <code>ShardDocs</code> in <code>resultIds</code>, may or may not be 
   *           part of a Cursor based request (method will NOOP if not needed)
   */
protected void populateNextCursorMarkFromMergedShards(ResponseBuilder rb) {
    final CursorMark lastCursorMark = rb.getCursorMark();
    if (null == lastCursorMark) {
        // NOOP
        return;
    }
    assert null != rb.resultIds : "resultIds was not set in ResponseBuilder";
    Collection<ShardDoc> docsOnThisPage = rb.resultIds.values();
    if (0 == docsOnThisPage.size()) {
        // nothing more matching query, re-use existing totem so user can "resume" 
        // search later if it makes sense for this sort.
        rb.setNextCursorMark(lastCursorMark);
        return;
    }
    ShardDoc lastDoc = null;
    // ShardDoc and rb.resultIds are weird structures to work with...
    for (ShardDoc eachDoc : docsOnThisPage) {
        if (null == lastDoc || lastDoc.positionInResponse < eachDoc.positionInResponse) {
            lastDoc = eachDoc;
        }
    }
    SortField[] sortFields = lastCursorMark.getSortSpec().getSort().getSort();
    List<Object> nextCursorMarkValues = new ArrayList<>(sortFields.length);
    for (SortField sf : sortFields) {
        if (sf.getType().equals(SortField.Type.SCORE)) {
            nextCursorMarkValues.add(lastDoc.score);
        } else {
            assert null != sf.getField() : "SortField has null field";
            List<Object> fieldVals = (List<Object>) lastDoc.sortFieldValues.get(sf.getField());
            nextCursorMarkValues.add(fieldVals.get(lastDoc.orderInShard));
        }
    }
    CursorMark nextCursorMark = lastCursorMark.createNext(nextCursorMarkValues);
    assert null != nextCursorMark : "null nextCursorMark";
    rb.setNextCursorMark(nextCursorMark);
}
Also used : CursorMark(org.apache.solr.search.CursorMark) ArrayList(java.util.ArrayList) SortField(org.apache.lucene.search.SortField) 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)

Example 2 with CursorMark

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

the class QueryComponent method prepare.

@Override
public void prepare(ResponseBuilder rb) throws IOException {
    SolrQueryRequest req = rb.req;
    SolrParams params = req.getParams();
    if (!params.getBool(COMPONENT_NAME, true)) {
        return;
    }
    SolrQueryResponse rsp = rb.rsp;
    // Set field flags    
    ReturnFields returnFields = new SolrReturnFields(req);
    rsp.setReturnFields(returnFields);
    int flags = 0;
    if (returnFields.wantsScore()) {
        flags |= SolrIndexSearcher.GET_SCORES;
    }
    rb.setFieldFlags(flags);
    String defType = params.get(QueryParsing.DEFTYPE, QParserPlugin.DEFAULT_QTYPE);
    // get it from the response builder to give a different component a chance
    // to set it.
    String queryString = rb.getQueryString();
    if (queryString == null) {
        // this is the normal way it's set.
        queryString = params.get(CommonParams.Q);
        rb.setQueryString(queryString);
    }
    try {
        QParser parser = QParser.getParser(rb.getQueryString(), defType, req);
        Query q = parser.getQuery();
        if (q == null) {
            // normalize a null query to a query that matches nothing
            q = new MatchNoDocsQuery();
        }
        rb.setQuery(q);
        String rankQueryString = rb.req.getParams().get(CommonParams.RQ);
        if (rankQueryString != null) {
            QParser rqparser = QParser.getParser(rankQueryString, defType, req);
            Query rq = rqparser.getQuery();
            if (rq instanceof RankQuery) {
                RankQuery rankQuery = (RankQuery) rq;
                rb.setRankQuery(rankQuery);
                MergeStrategy mergeStrategy = rankQuery.getMergeStrategy();
                if (mergeStrategy != null) {
                    rb.addMergeStrategy(mergeStrategy);
                    if (mergeStrategy.handlesMergeFields()) {
                        rb.mergeFieldHandler = mergeStrategy;
                    }
                }
            } else {
                throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "rq parameter must be a RankQuery");
            }
        }
        rb.setSortSpec(parser.getSortSpec(true));
        rb.setQparser(parser);
        final String cursorStr = rb.req.getParams().get(CursorMarkParams.CURSOR_MARK_PARAM);
        if (null != cursorStr) {
            final CursorMark cursorMark = new CursorMark(rb.req.getSchema(), rb.getSortSpec());
            cursorMark.parseSerializedTotem(cursorStr);
            rb.setCursorMark(cursorMark);
        }
        String[] fqs = req.getParams().getParams(CommonParams.FQ);
        if (fqs != null && fqs.length != 0) {
            List<Query> filters = rb.getFilters();
            // if filters already exists, make a copy instead of modifying the original
            filters = filters == null ? new ArrayList<>(fqs.length) : new ArrayList<>(filters);
            for (String fq : fqs) {
                if (fq != null && fq.trim().length() != 0) {
                    QParser fqp = QParser.getParser(fq, req);
                    fqp.setIsFilter(true);
                    filters.add(fqp.getQuery());
                }
            }
            // if filter cache is disabled
            if (!filters.isEmpty()) {
                rb.setFilters(filters);
            }
        }
    } catch (SyntaxError e) {
        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
    }
    if (params.getBool(GroupParams.GROUP, false)) {
        prepareGrouping(rb);
    } else {
        //Validate only in case of non-grouping search.
        if (rb.getSortSpec().getCount() < 0) {
            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "'rows' parameter cannot be negative");
        }
    }
    //Input validation.
    if (rb.getSortSpec().getOffset() < 0) {
        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "'start' parameter cannot be negative");
    }
}
Also used : SolrQueryResponse(org.apache.solr.response.SolrQueryResponse) SolrReturnFields(org.apache.solr.search.SolrReturnFields) ReturnFields(org.apache.solr.search.ReturnFields) Query(org.apache.lucene.search.Query) MatchNoDocsQuery(org.apache.lucene.search.MatchNoDocsQuery) RankQuery(org.apache.solr.search.RankQuery) CursorMark(org.apache.solr.search.CursorMark) MatchNoDocsQuery(org.apache.lucene.search.MatchNoDocsQuery) ArrayList(java.util.ArrayList) SolrReturnFields(org.apache.solr.search.SolrReturnFields) RankQuery(org.apache.solr.search.RankQuery) SolrQueryRequest(org.apache.solr.request.SolrQueryRequest) SyntaxError(org.apache.solr.search.SyntaxError) QParser(org.apache.solr.search.QParser) SolrParams(org.apache.solr.common.params.SolrParams) ModifiableSolrParams(org.apache.solr.common.params.ModifiableSolrParams) SolrException(org.apache.solr.common.SolrException)

Aggregations

ArrayList (java.util.ArrayList)2 CursorMark (org.apache.solr.search.CursorMark)2 List (java.util.List)1 MatchNoDocsQuery (org.apache.lucene.search.MatchNoDocsQuery)1 Query (org.apache.lucene.search.Query)1 SortField (org.apache.lucene.search.SortField)1 SolrDocumentList (org.apache.solr.common.SolrDocumentList)1 SolrException (org.apache.solr.common.SolrException)1 ModifiableSolrParams (org.apache.solr.common.params.ModifiableSolrParams)1 SolrParams (org.apache.solr.common.params.SolrParams)1 NamedList (org.apache.solr.common.util.NamedList)1 SolrQueryRequest (org.apache.solr.request.SolrQueryRequest)1 SolrQueryResponse (org.apache.solr.response.SolrQueryResponse)1 DocList (org.apache.solr.search.DocList)1 QParser (org.apache.solr.search.QParser)1 RankQuery (org.apache.solr.search.RankQuery)1 ReturnFields (org.apache.solr.search.ReturnFields)1 SolrReturnFields (org.apache.solr.search.SolrReturnFields)1 SyntaxError (org.apache.solr.search.SyntaxError)1