Example usage for org.apache.lucene.search IndexSearcher explain

List of usage examples for org.apache.lucene.search IndexSearcher explain

Introduction

In this page you can find the example usage for org.apache.lucene.search IndexSearcher explain.

Prototype

protected Explanation explain(Weight weight, int doc) throws IOException 

Source Link

Document

Expert: low-level implementation method Returns an Explanation that describes how doc scored against weight.

Usage

From source file:com.nuvolect.deepdive.lucene.Search.java

/**
 * Return results for a search along a specific path.  If the path is changed or new
 * create an index./*from   w w  w  . java2s  . c  o m*/
 * @param searchQuery
 * @param searchPath
 * @return
 */
public static JSONObject search(String searchQuery, String volumeId, String searchPath) {

    JSONObject result = new JSONObject();
    JSONArray jsonArray = new JSONArray();
    Context ctx = App.getContext();

    DirectoryReader ireader = null;
    ScoreDoc[] scoreDocs = null;
    String error = "";

    preSearch(volumeId, searchPath);
    try {
        ireader = DirectoryReader.open(m_directory);
    } catch (IOException e) {
        LogUtil.logException(LogUtil.LogType.SEARCH, e);
        error += e.toString();
    }
    IndexSearcher isearcher = new IndexSearcher(ireader);
    Query query = null;

    try {

        LogUtil.log(LogUtil.LogType.SEARCH,
                "query: " + searchQuery + ", vid: " + volumeId + ", path: " + searchPath);

        // Parse a simple query that searches for "text":
        QueryParser parser = new QueryParser(CConst.FIELD_CONTENT, m_analyzer);
        query = parser.parse(searchQuery);
        TopScoreDocCollector collector = TopScoreDocCollector.create(MAX_HITS);
        isearcher.search(query, collector);
        scoreDocs = collector.topDocs().scoreDocs;

    } catch (ParseException | IOException e) {
        LogUtil.logException(LogUtil.LogType.SEARCH, e);
        error += e.toString();
    }
    // Iterate through the results creating an object for each file
    HashMap<String, Integer> hitCounts = new HashMap<>();
    HashMap<String, Integer> hitIndexes = new HashMap<>();

    /**
     * First iterate the hit list and count duplicates based on file path.
     */
    for (int ii = 0; scoreDocs != null && ii < scoreDocs.length; ++ii) {

        Document hitDoc = null;
        int fileHits = 1;
        try {
            hitDoc = isearcher.doc(scoreDocs[ii].doc);

            Explanation explanation = isearcher.explain(query, scoreDocs[ii].doc);
            Explanation[] details = explanation.getDetails();
            String description = details[0].getDescription();

            /**
             * FIXME, find a better way to count hits in each file
             */
            if (description.contains("=")) {

                String[] lineParts = description.split("=");
                String[] elementParts = lineParts[2].split(Pattern.quote(")"));
                if (elementParts.length > 0) {

                    fileHits = ((int) Double.parseDouble(elementParts[0]));
                }
            }

        } catch (IOException e) {
            LogUtil.logException(LogUtil.LogType.SEARCH, e);
            error += e.toString();
        }
        String filePath = hitDoc.get((CConst.FIELD_PATH));

        if (hitCounts.containsKey(filePath)) {

            hitCounts.put(filePath, hitCounts.get(filePath) + fileHits);
        } else {
            hitCounts.put(filePath, fileHits);
            hitIndexes.put(filePath, ii);
        }
    }

    /**
     * Iterate over each unique hit and save the results
     */
    for (Map.Entry<String, Integer> uniqueHit : hitIndexes.entrySet()) {

        Document hitDoc = null;
        try {
            hitDoc = isearcher.doc(scoreDocs[uniqueHit.getValue()].doc);
        } catch (IOException e) {
            LogUtil.logException(LogUtil.LogType.SEARCH, e);
            error += e.toString();
        }
        String file_name = hitDoc.get((CConst.FIELD_FILENAME));
        String file_path = hitDoc.get((CConst.FIELD_PATH));
        try {
            String folder_url = OmniHash.getStartPathUrl(ctx, volumeId, file_path);

            JSONObject hitObj = new JSONObject();
            hitObj.put("volume_id", volumeId);
            hitObj.put("file_path", file_path);
            hitObj.put("file_name", file_name);
            hitObj.put("folder_url", folder_url);
            hitObj.put("num_hits", hitCounts.get(file_path));
            hitObj.put("error", error);
            jsonArray.put(hitObj);

        } catch (Exception e) {
            LogUtil.logException(LogUtil.LogType.SEARCH, e);
        }
    }
    int num_hits = scoreDocs != null ? scoreDocs.length : 0;

    try {
        result.put("hits", jsonArray != null ? jsonArray : new JSONArray());
        result.put("num_hits", num_hits);
        result.put("error", error);

        ireader.close();
        m_directory.close();

    } catch (JSONException | IOException e) {
        LogUtil.logException(LogUtil.LogType.SEARCH, e);
    }

    return result;
}

From source file:com.redhat.satellite.search.index.IndexManager.java

License:Open Source License

private void debugExplainResults(String indexName, Hits hits, IndexSearcher searcher, Query q,
        Set<Term> queryTerms) throws IOException {
    log.debug("Parsed Query is " + q.toString());
    log.debug("Looking at index:  " + indexName);
    for (int i = 0; i < hits.length(); i++) {
        if ((i < 10)) {
            Document doc = hits.doc(i);
            Float score = hits.score(i);
            Explanation ex = searcher.explain(q, hits.id(i));
            log.debug("Looking at hit<" + i + ", " + hits.id(i) + ", " + score + ">: " + doc);
            log.debug("Explanation: " + ex);
            MatchingField match = new MatchingField(q.toString(), doc, queryTerms);
            String fieldName = match.getFieldName();
            String fieldValue = match.getFieldValue();
            log.debug("Guessing that matched fieldName is " + fieldName + " = " + fieldValue);
        }//w  ww.  j  av  a2 s .  c o  m
    }
}

From source file:com.tekstosense.stemmer.index.Indexer.java

License:Open Source License

/**
 * Searcher.//from   w w w . j av a  2s.  c o  m
 *
 * @throws IOException
 *             Signals that an I/O exception has occurred.
 * @throws QueryNodeException
 *             the query node exception
 * @throws ParseException
 *             the parse exception
 */
private static void searcher() throws IOException, QueryNodeException, ParseException {
    Path indexDirectoryPath = new File(INDEX_PATH).toPath();
    FSDirectory indexDirectory = new SimpleFSDirectory(indexDirectoryPath);
    DirectoryReader ireader = DirectoryReader.open(indexDirectory);
    IndexSearcher isearcher = new IndexSearcher(ireader);
    QueryParser parser = new QueryParser("title", new StandardAnalyzer());
    Query query = parser.parse("\"Lucene in Action\"");

    TopScoreDocCollector collector = TopScoreDocCollector.create(10);
    isearcher.search(query, new PositiveScoresOnlyCollector(collector));
    TopDocs topDocs = collector.topDocs();
    Set<String> fields = new HashSet<String>();
    fields.add("title");
    fields.add("isbn");
    for (ScoreDoc result : topDocs.scoreDocs) {
        Document doc = isearcher.doc(result.doc, fields);

        if (LOGGER.isInfoEnabled()) {

            LOGGER.info("--- Title :  " + doc.getField("title").stringValue() + " ---");
            LOGGER.info("--- ISBN : " + doc.getField("isbn").stringValue() + " ---");
            LOGGER.info(isearcher.explain(query, result.doc));
        }

    }

}

From source file:de.dkt.eservices.elucene.indexmanagement.SearchFiles.java

License:Apache License

/**
 * Searches a query against a field of an index and return hitsToReturn documents.
 * @param index index where to search for the query text
 * @param field document field against what to match the query
 * @param queryString text of the input query
 * @param hitsToReturn number of documents to be returned
 * @return JSON format string containing the results information and content
 * @throws ExternalServiceFailedException
 *///from  ww w  . ja  v a2 s  .c om
public static JSONObject search(String index, String sFields, String sAnalyzers, String queryType,
        String queryString, String language, int hitsToReturn) throws ExternalServiceFailedException {
    try {
        //         System.out.println(index+"__"+sFields+"__"+sAnalyzers+"__"+queryType+"__"+language+"__"+hitsToReturn);
        //         System.out.println(indexDirectory);
        Date start = new Date();

        File f = FileFactory.generateFileInstance(indexDirectory + index);
        if (f == null || !f.exists()) {
            throw new ExternalServiceFailedException(
                    "Specified index [" + indexDirectory + index + "] does not exists.");
        }
        logger.info("Searching in folder: " + f.getAbsolutePath());
        Directory dir = FSDirectory.open(f);
        IndexReader reader = DirectoryReader.open(dir);
        IndexSearcher searcher = new IndexSearcher(reader);

        //         System.out.println(reader.docFreq(new Term("content", "madrid")));

        Document doc = reader.document(0);
        //         System.out.println(reader.numDocs());
        //         System.out.println(doc);

        String[] fields = sFields.split(";");
        String[] analyzers = sAnalyzers.split(";");
        if (fields.length != analyzers.length) {
            logger.error("The number of fields and analyzers is different");
            throw new BadRequestException("The number of fields and analyzers is different");
        }

        //System.out.println("CHECK IF THE QUERY IS WORKING PROPERLY: "+queryString);
        Query query = OwnQueryParser.parseQuery(queryType, queryString, fields, analyzers, language);

        //System.out.println("\t QUERY: "+query);

        TopDocs results = searcher.search(query, hitsToReturn);

        Explanation exp = searcher.explain(query, 0);
        //         System.out.println("EXPLANATION: "+exp);

        //         System.out.println("TOTAL HITS: " + results.totalHits);

        Date end = new Date();
        logger.info("Time: " + (end.getTime() - start.getTime()) + "ms");
        //         System.out.println("Time: "+(end.getTime()-start.getTime())+"ms");

        JSONObject resultModel = JSONLuceneResultConverter.convertResults(query, searcher, results);
        reader.close();
        return resultModel;
    } catch (IOException e) {
        e.printStackTrace();
        throw new ExternalServiceFailedException("IOException with message: " + e.getMessage());
    }
}

From source file:de.innovationgate.wgpublisher.lucene.LuceneManager.java

License:Open Source License

public Explanation explain(Query query, int doc)
        throws CorruptIndexException, IOException, InterruptedException {
    IndexSearcher searcher = getIndexSearcher();
    _indexSearcherSemaphore.acquire();/*  www.  j  av a2s.co  m*/
    try {
        return searcher.explain(query, doc);
    } finally {
        _indexSearcherSemaphore.release();
    }
}

From source file:document_search.MultiQuerySearch.java

License:Open Source License

public static List<MultiQueryResults> search(Index i, int docLimit, String searchField, Analyzer a,
        String... queries) {// w  w w.  j a  v a 2  s. co  m
    ParseWrapper parser = new ParseWrapper(new QueryParser(searchField, a));

    // Parse all available results
    List<QueryPair> queryList = Arrays.asList(queries).stream().map(parser::parseQuery)
            .filter(query -> query != null).collect(Collectors.toList());

    // Create the overall query
    BooleanQuery query = new BooleanQuery();
    for (QueryPair pair : queryList) {
        query.add(pair.query, BooleanClause.Occur.SHOULD);
    }

    // FIXME: We should not have index searchers here, but we still do! :-( Fuck Lucene and its vast plots of, features...
    IndexSearcher searcher = new IndexSearcher(i.getIndexer().getReader());

    // TODO: Refactor this because it looks terrible, functional style is better, but the functional isn't good...
    List<MultiQueryResults> queryResults = Collections.checkedList(new ArrayList<>(), MultiQueryResults.class);
    for (Index.IndexDocument doc : i.runQuery(query, docLimit)) {
        // Create new multi query results
        MultiQueryResults results = new MultiQueryResults(doc.id, doc.score, Arrays.asList(queries));

        // Explain the individual query results
        for (QueryPair queryPair : queryList) {
            try {
                double score = searcher.explain(queryPair.query, doc.lucene_id).getValue();
                QueryResults individualResults = new QueryResults(doc.id, queryPair.term, score);
                results.addQueryResult(individualResults);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // Add the Multi-query results to the overall list
        queryResults.add(results);
    }
    return queryResults;
}

From source file:edu.stanford.muse.index.Indexer.java

License:Apache License

/**
 * returns collection of docIds of the Lucene docs that hit, at least
 * threshold times./*from  w  w w  .  ja v a  2s.  c  o  m*/
 * warning! only looks up body field, no others
  * Caution: This code is not to be touched, unless something is being optimised
  * Introducing something here can seriously affect the search times.
 */
private Pair<Collection<String>, Integer> luceneLookupAsDocIdsWithTotalHits(String q, int threshold,
        IndexSearcher searcher, QueryType qt, int lt)
        throws IOException, ParseException, GeneralSecurityException, ClassNotFoundException {
    Collection<String> result = new ArrayList<String>();

    //   String escaped_q = escapeRegex(q); // to mimic built-in regex support
    //TODO: There should also be a general query type that takes any query with field param, i.e. without parser
    Query query;
    if (qt == QueryType.ORIGINAL)
        query = parserOriginal.parse(q);
    else if (qt == QueryType.SUBJECT)
        query = parserSubject.parse(q);
    else if (qt == QueryType.CORRESPONDENTS)
        query = parserCorrespondents.parse(q);
    else if (qt == QueryType.REGEX) {
        query = new BooleanQuery();
        /**
         * Note: this is not a spanning (i.e. doesn't search over more than
         * one token) regexp, for spanning regexp use: body_unanlyzed and
         * title_unanlyzed fields instead
         */
        Query query1 = new RegexpQuery(new Term("body", q), RegExp.ALL);
        Query query2 = new RegexpQuery(new Term("title", q), RegExp.ALL);
        ((BooleanQuery) query).add(query1, org.apache.lucene.search.BooleanClause.Occur.SHOULD);
        ((BooleanQuery) query).add(query2, org.apache.lucene.search.BooleanClause.Occur.SHOULD);
    } else /* if (qt == QueryType.PRESET_REGEX) {
           query = new BooleanQuery();
           if(presetQueries != null) {
           for (String pq : presetQueries) {
             Query query1 = new RegexpQuery(new Term("body", pq), RegExp.ALL);
             Query query2 = new RegexpQuery(new Term("title", pq), RegExp.ALL);
             ((BooleanQuery) query).add(query1, org.apache.lucene.search.BooleanClause.Occur.SHOULD);
             ((BooleanQuery) query).add(query2, org.apache.lucene.search.BooleanClause.Occur.SHOULD);
           }
           log.info("Doing a preset regex search");
           }else{
           log.warn("Preset queries is not initialised");
           }
           } else */ if (qt == QueryType.META) {
        query = parserMeta.parse(q);
    } else
        query = parser.parse(q);

    //      query = convertRegex(query);
    long st = System.currentTimeMillis();
    int totalHits = 0;
    ScoreDoc[] hits = null;
    if (query != null) {
        TopDocs tds = searcher.search(query, null, lt);
        log.info("Took: " + (System.currentTimeMillis() - st) + "ms for query:" + query);
        hits = tds.scoreDocs;
        totalHits = tds.totalHits;
    } else {
        log.error("Query is null!!");
    }
    // this logging causes a 50% overhead on the query -- maybe enable it only for debugging
    // log.info (hits.length + " hits for query " + Util.ellipsize(q, 30) + " => " + Util.ellipsize(escaped_q, 30) + " = " + Util.ellipsize(query.toString(), 30) + " :");

    // Iterate through the results:

    // TODO: not very pretty code here to determine dir_name which selects the cache to use
    Util.softAssert(searcher == isearcher || searcher == isearcher_blob);
    String dir_name = searcher == isearcher ? INDEX_NAME_EMAILS : INDEX_NAME_ATTACHMENTS;

    Map<Integer, String> map = dirNameToDocIdMap.get(dir_name);
    if (map == null) {
        map = new LinkedHashMap<Integer, String>();
        dirNameToDocIdMap.put(dir_name, map);
        log.info("Adding new entry for dir name to docIdMap");
    } else {
        log.info("Existing entry for dir name to docIdMap");
    }

    int n_added = 0;
    log.info("Found: " + hits.length + " hits for query: " + q);
    for (int i = 0; i < hits.length; i++) {
        int ldocId = hits[i].doc; // this is the lucene doc id, we need to map it to our doc id.

        String docId = null; // this will be our doc id

        // try to use the new fieldcache id's
        // if this works, we can get rid of the dirNameToDocIdMap
        try {
            docId = (searcher == isearcher) ? contentDocIds.get(ldocId) : blobDocIds.get(ldocId);
        } catch (Exception e) {
            Util.print_exception(e, log);
            continue;
        }

        if (threshold <= 1) {
            // common case: threshold is 1.
            result.add(docId);
            n_added++;
        } else {
            // more expensive, do it only if threshold is > 1
            Explanation expl = searcher.explain(query, hits[i].doc);
            Explanation[] details = expl.getDetails();
            // NB: a catch here is that details.length doesn't reflect the actual # of hits for the query.
            // sometimes, for a single hit, there are 2 entries, a ComplexExplanation and an Explanation.
            // not sure why, but is somewhat corroborated by the code:
            // http://massapi.com/class/ex/Explanation.html
            // showing a single hit creating both a C.E and an E.
            // a more robust approach might be to look for the summary to end with product of: , sum of: etc.
            // e.g. http://www.gossamer-threads.com/lists/lucene/java-dev/49706
            // but for now, we'll count only the number of ComplexExplanation and check if its above threshold
            //            log.info("doc id " + hits[i].toString() + " #details = " + details.length);

            // HORRIBLE HACK! - because we don't know a better way to find the threshold
            outer: for (Explanation detail : details) {
                // log.info(detail.getClass().getName());

                if (detail instanceof ComplexExplanation) {
                    ComplexExplanation ce = (ComplexExplanation) detail;
                    String s = ce.toString();
                    int total_tf = 0;
                    while (true) {
                        int idx = s.indexOf("tf(termFreq(");
                        if (idx < 0)
                            break outer;
                        s = s.substring(idx);
                        idx = s.indexOf("=");
                        if (idx < 0)
                            break outer;
                        s = s.substring(idx + 1);
                        int idx1 = s.indexOf(")");
                        if (idx < 0)
                            break outer;
                        String num_str = s.substring(0, idx1);
                        int num = 0;
                        try {
                            num = Integer.parseInt(num_str);
                        } catch (Exception e) {
                            log.warn("ERROR parsing complex expl: " + num_str);
                        }
                        total_tf += num;
                        if (total_tf >= threshold) {
                            result.add(docId);
                            n_added++;
                            break outer;
                        }
                    }
                }
            }
        }
    }
    log.info(n_added + " docs added to docIdMap cache");
    return new Pair<Collection<String>, Integer>(result, totalHits);
}

From source file:lia.searching.Explainer.java

License:Apache License

public static void main(String[] args) throws Exception {
    //    if (args.length != 2) {
    //      System.err.println("Usage: Explainer <index dir> <query>");
    //      System.exit(1);
    //    }//from  w  ww  .ja va 2 s.c  o  m

    //    String indexDir = args[0];
    //    String queryExpression = args[1];

    String indexDir = "indexes/MeetLucene";
    String queryExpression = "junit";

    Directory directory = FSDirectory.open(new File(indexDir));
    QueryParser parser = new QueryParser(Version.LUCENE_30, "contents", new SimpleAnalyzer());
    Query query = parser.parse(queryExpression);

    System.out.println("Query: " + queryExpression);

    IndexSearcher searcher = new IndexSearcher(directory);
    TopDocs topDocs = searcher.search(query, 10);

    for (ScoreDoc match : topDocs.scoreDocs) {
        Explanation explanation = searcher.explain(query, match.doc); //#A

        System.out.println("----------");
        Document doc = searcher.doc(match.doc);
        System.out.println(doc.get("title"));
        System.out.println(explanation.toString()); //#B
    }
    searcher.close();
    directory.close();
}

From source file:org.apache.jackrabbit.oak.plugins.index.lucene.LucenePropertyIndex.java

License:Apache License

@Override
public Cursor query(final IndexPlan plan, NodeState rootState) {
    final Filter filter = plan.getFilter();
    final Sort sort = getSort(plan);
    final PlanResult pr = getPlanResult(plan);
    QueryEngineSettings settings = filter.getQueryEngineSettings();
    Iterator<LuceneResultRow> itr = new AbstractIterator<LuceneResultRow>() {
        private final Deque<LuceneResultRow> queue = Queues.newArrayDeque();
        private final Set<String> seenPaths = Sets.newHashSet();
        private ScoreDoc lastDoc;
        private int nextBatchSize = LUCENE_QUERY_BATCH_SIZE;
        private boolean noDocs = false;
        private long lastSearchIndexerVersion;

        @Override/* w  w  w.j  a  v a2 s  . c o  m*/
        protected LuceneResultRow computeNext() {
            while (!queue.isEmpty() || loadDocs()) {
                return queue.remove();
            }
            return endOfData();
        }

        private LuceneResultRow convertToRow(ScoreDoc doc, IndexSearcher searcher, String excerpt,
                Facets facets, String explanation) throws IOException {
            IndexReader reader = searcher.getIndexReader();
            //TODO Look into usage of field cache for retrieving the path
            //instead of reading via reader if no of docs in index are limited
            PathStoredFieldVisitor visitor = new PathStoredFieldVisitor();
            reader.document(doc.doc, visitor);
            String path = visitor.getPath();
            if (path != null) {
                if ("".equals(path)) {
                    path = "/";
                }
                if (pr.isPathTransformed()) {
                    String originalPath = path;
                    path = pr.transformPath(path);

                    if (path == null) {
                        LOG.trace("Ignoring path {} : Transformation returned null", originalPath);
                        return null;
                    }

                    // avoid duplicate entries
                    if (seenPaths.contains(path)) {
                        LOG.trace("Ignoring path {} : Duplicate post transformation", originalPath);
                        return null;
                    }
                    seenPaths.add(path);
                }

                LOG.trace("Matched path {}", path);
                return new LuceneResultRow(path, doc.score, excerpt, facets, explanation);
            }
            return null;
        }

        /**
         * Loads the lucene documents in batches
         * @return true if any document is loaded
         */
        private boolean loadDocs() {

            if (noDocs) {
                return false;
            }

            ScoreDoc lastDocToRecord = null;

            final IndexNode indexNode = acquireIndexNode(plan);
            checkState(indexNode != null);
            try {
                IndexSearcher searcher = indexNode.getSearcher();
                LuceneRequestFacade luceneRequestFacade = getLuceneRequest(plan, augmentorFactory,
                        searcher.getIndexReader());
                if (luceneRequestFacade.getLuceneRequest() instanceof Query) {
                    Query query = (Query) luceneRequestFacade.getLuceneRequest();

                    CustomScoreQuery customScoreQuery = getCustomScoreQuery(plan, query);

                    if (customScoreQuery != null) {
                        query = customScoreQuery;
                    }

                    checkForIndexVersionChange(searcher);

                    TopDocs docs;
                    long start = PERF_LOGGER.start();
                    while (true) {
                        if (lastDoc != null) {
                            LOG.debug("loading the next {} entries for query {}", nextBatchSize, query);
                            if (sort == null) {
                                docs = searcher.searchAfter(lastDoc, query, nextBatchSize);
                            } else {
                                docs = searcher.searchAfter(lastDoc, query, nextBatchSize, sort);
                            }
                        } else {
                            LOG.debug("loading the first {} entries for query {}", nextBatchSize, query);
                            if (sort == null) {
                                docs = searcher.search(query, nextBatchSize);
                            } else {
                                docs = searcher.search(query, nextBatchSize, sort);
                            }
                        }
                        PERF_LOGGER.end(start, -1, "{} ...", docs.scoreDocs.length);
                        nextBatchSize = (int) Math.min(nextBatchSize * 2L, 100000);

                        long f = PERF_LOGGER.start();
                        Facets facets = FacetHelper.getFacets(searcher, query, docs, plan,
                                indexNode.getDefinition().isSecureFacets());
                        PERF_LOGGER.end(f, -1, "facets retrieved");

                        PropertyRestriction restriction = filter.getPropertyRestriction(QueryImpl.REP_EXCERPT);
                        boolean addExcerpt = restriction != null && restriction.isNotNullRestriction();

                        restriction = filter.getPropertyRestriction(QueryImpl.OAK_SCORE_EXPLANATION);
                        boolean addExplain = restriction != null && restriction.isNotNullRestriction();

                        Analyzer analyzer = indexNode.getDefinition().getAnalyzer();

                        FieldInfos mergedFieldInfos = null;
                        if (addExcerpt) {
                            // setup highlighter
                            QueryScorer scorer = new QueryScorer(query);
                            scorer.setExpandMultiTermQuery(true);
                            highlighter.setFragmentScorer(scorer);
                            mergedFieldInfos = MultiFields.getMergedFieldInfos(searcher.getIndexReader());
                        }

                        for (ScoreDoc doc : docs.scoreDocs) {
                            String excerpt = null;
                            if (addExcerpt) {
                                excerpt = getExcerpt(query, analyzer, searcher, doc, mergedFieldInfos);
                            }

                            String explanation = null;
                            if (addExplain) {
                                explanation = searcher.explain(query, doc.doc).toString();
                            }

                            LuceneResultRow row = convertToRow(doc, searcher, excerpt, facets, explanation);
                            if (row != null) {
                                queue.add(row);
                            }
                            lastDocToRecord = doc;
                        }

                        if (queue.isEmpty() && docs.scoreDocs.length > 0) {
                            //queue is still empty but more results can be fetched
                            //from Lucene so still continue
                            lastDoc = lastDocToRecord;
                        } else {
                            break;
                        }
                    }
                } else if (luceneRequestFacade.getLuceneRequest() instanceof SpellcheckHelper.SpellcheckQuery) {
                    String aclCheckField = indexNode.getDefinition().isFullTextEnabled() ? FieldNames.FULLTEXT
                            : FieldNames.SPELLCHECK;
                    noDocs = true;
                    SpellcheckHelper.SpellcheckQuery spellcheckQuery = (SpellcheckHelper.SpellcheckQuery) luceneRequestFacade
                            .getLuceneRequest();
                    SuggestWord[] suggestWords = SpellcheckHelper.getSpellcheck(spellcheckQuery);

                    // ACL filter spellchecks
                    QueryParser qp = new QueryParser(Version.LUCENE_47, aclCheckField,
                            indexNode.getDefinition().getAnalyzer());
                    for (SuggestWord suggestion : suggestWords) {
                        Query query = qp.createPhraseQuery(aclCheckField,
                                QueryParserBase.escape(suggestion.string));

                        query = addDescendantClauseIfRequired(query, plan);

                        TopDocs topDocs = searcher.search(query, 100);
                        if (topDocs.totalHits > 0) {
                            for (ScoreDoc doc : topDocs.scoreDocs) {
                                Document retrievedDoc = searcher.doc(doc.doc);
                                String prefix = filter.getPath();
                                if (prefix.length() == 1) {
                                    prefix = "";
                                }
                                if (filter.isAccessible(prefix + retrievedDoc.get(FieldNames.PATH))) {
                                    queue.add(new LuceneResultRow(suggestion.string));
                                    break;
                                }
                            }
                        }
                    }

                } else if (luceneRequestFacade.getLuceneRequest() instanceof SuggestHelper.SuggestQuery) {
                    SuggestHelper.SuggestQuery suggestQuery = (SuggestHelper.SuggestQuery) luceneRequestFacade
                            .getLuceneRequest();
                    noDocs = true;

                    List<Lookup.LookupResult> lookupResults = SuggestHelper
                            .getSuggestions(indexNode.getLookup(), suggestQuery);

                    QueryParser qp = new QueryParser(Version.LUCENE_47, FieldNames.SUGGEST,
                            indexNode.getDefinition().isSuggestAnalyzed()
                                    ? indexNode.getDefinition().getAnalyzer()
                                    : SuggestHelper.getAnalyzer());

                    // ACL filter suggestions
                    for (Lookup.LookupResult suggestion : lookupResults) {
                        Query query = qp.parse("\"" + QueryParserBase.escape(suggestion.key.toString()) + "\"");

                        query = addDescendantClauseIfRequired(query, plan);

                        TopDocs topDocs = searcher.search(query, 100);
                        if (topDocs.totalHits > 0) {
                            for (ScoreDoc doc : topDocs.scoreDocs) {
                                Document retrievedDoc = searcher.doc(doc.doc);
                                String prefix = filter.getPath();
                                if (prefix.length() == 1) {
                                    prefix = "";
                                }
                                if (filter.isAccessible(prefix + retrievedDoc.get(FieldNames.PATH))) {
                                    queue.add(new LuceneResultRow(suggestion.key.toString(), suggestion.value));
                                    break;
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                LOG.warn("query via {} failed.", LucenePropertyIndex.this, e);
            } finally {
                indexNode.release();
            }

            if (lastDocToRecord != null) {
                this.lastDoc = lastDocToRecord;
            }

            return !queue.isEmpty();
        }

        private void checkForIndexVersionChange(IndexSearcher searcher) {
            long currentVersion = getVersion(searcher);
            if (currentVersion != lastSearchIndexerVersion && lastDoc != null) {
                lastDoc = null;
                LOG.debug("Change in index version detected {} => {}. Query would be performed without "
                        + "offset", currentVersion, lastSearchIndexerVersion);
            }
            this.lastSearchIndexerVersion = currentVersion;
        }
    };
    SizeEstimator sizeEstimator = new SizeEstimator() {
        @Override
        public long getSize() {
            IndexNode indexNode = acquireIndexNode(plan);
            checkState(indexNode != null);
            try {
                IndexSearcher searcher = indexNode.getSearcher();
                LuceneRequestFacade luceneRequestFacade = getLuceneRequest(plan, augmentorFactory,
                        searcher.getIndexReader());
                if (luceneRequestFacade.getLuceneRequest() instanceof Query) {
                    Query query = (Query) luceneRequestFacade.getLuceneRequest();
                    TotalHitCountCollector collector = new TotalHitCountCollector();
                    searcher.search(query, collector);
                    int totalHits = collector.getTotalHits();
                    LOG.debug("Estimated size for query {} is {}", query, totalHits);
                    return totalHits;
                }
                LOG.debug("estimate size: not a Query: {}", luceneRequestFacade.getLuceneRequest());
            } catch (IOException e) {
                LOG.warn("query via {} failed.", LucenePropertyIndex.this, e);
            } finally {
                indexNode.release();
            }
            return -1;
        }
    };
    return new LucenePathCursor(itr, plan, settings, sizeEstimator);
}

From source file:org.apache.solr.search.function.TestOrdValues.java

License:Apache License

private void doTestRank(String field, boolean inOrder) throws Exception {
    IndexReader r = DirectoryReader.open(dir);
    IndexSearcher s = newSearcher(r);
    ValueSource vs;/*  w w w.  ja v a  2 s . com*/
    if (inOrder) {
        vs = new OrdFieldSource(field);
    } else {
        vs = new ReverseOrdFieldSource(field);
    }

    Query q = new FunctionQuery(vs);
    log("test: " + q);
    QueryUtils.check(random(), q, s);
    ScoreDoc[] h = s.search(q, 1000).scoreDocs;
    assertEquals("All docs should be matched!", N_DOCS, h.length);
    String prevID = inOrder ? "IE" // greater than all ids of docs in this test ("ID0001", etc.)
            : "IC"; // smaller than all ids of docs in this test ("ID0001", etc.)

    for (int i = 0; i < h.length; i++) {
        String resID = s.doc(h[i].doc).get(ID_FIELD);
        log(i + ".   score=" + h[i].score + "  -  " + resID);
        log(s.explain(q, h[i].doc));
        if (inOrder) {
            assertTrue("res id " + resID + " should be < prev res id " + prevID, resID.compareTo(prevID) < 0);
        } else {
            assertTrue("res id " + resID + " should be > prev res id " + prevID, resID.compareTo(prevID) > 0);
        }
        prevID = resID;
    }
    r.close();
}