package lux.functions; import java.io.IOException; import lux.Evaluator; import lux.solr.CloudSearchIterator; import lux.xpath.FunCall; import net.sf.saxon.om.StructuredQName; import net.sf.saxon.trans.XPathException; import net.sf.saxon.tree.iter.SingletonIterator; import net.sf.saxon.tree.iter.UnfailingIterator; import net.sf.saxon.value.BooleanValue; import net.sf.saxon.value.SequenceType; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Query; import org.apache.lucene.search.Scorer; /** * <code>function lux:exists($query as item()) as xs:integer</code> *<p> * This function tests whether a search has any results. It is faster and uses less memory * than calling fn:exists() on the search results themselves because it does not need to load * any result documents in memory. See {@link Search} for an explanation of the supported * $query formats. * </p> */ public class Exists extends SearchBase { public Exists() { } @Override public StructuredQName getFunctionQName() { return new StructuredQName("lux", FunCall.LUX_NAMESPACE, "exists"); } @Override public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) { return SequenceType.SINGLE_BOOLEAN; } @Override public boolean trustResultType () { return true; } @Override public UnfailingIterator<BooleanValue> iterate (Query query, Evaluator saxon, String[] sortCriteria, int start) throws XPathException { long t = System.currentTimeMillis(); boolean exists = false; try { DocIdSetIterator iter = saxon.getSearcher().search(query); exists = (iter.nextDoc() != Scorer.NO_MORE_DOCS); } catch (IOException e) { throw new XPathException (e); } saxon.getQueryStats().totalTime = System.currentTimeMillis() - t; if (exists) { ++ saxon.getQueryStats().docCount; } return SingletonIterator.makeIterator(BooleanValue.get(exists)); } @Override protected UnfailingIterator<BooleanValue> iterateDistributed(String query, QueryParser queryParser, Evaluator eval, String[] sortCriteria, int start) throws XPathException { try { long count = new CloudSearchIterator (eval, query, queryParser, sortCriteria, start).count(); return SingletonIterator.makeIterator(BooleanValue.get(count > 0)); } catch (Exception e) { throw new XPathException (e); } } } /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */