public List<LookupResult> lookup(CharSequence key,BooleanQuery contextQuery,int num,boolean allTermsRequired,boolean doHighlight) throws IOException {
  if (searcherMgr == null) {
    throw new IllegalStateException("suggester was not built");
  }
  final BooleanClause.Occur occur;
  if (allTermsRequired) {
    occur=BooleanClause.Occur.MUST;
  }
 else {
    occur=BooleanClause.Occur.SHOULD;
  }
  BooleanQuery.Builder query;
  Set<String> matchedTokens;
  String prefixToken=null;
  try (TokenStream ts=queryAnalyzer.tokenStream("",new StringReader(key.toString()))){
    ts.reset();
    final CharTermAttribute termAtt=ts.addAttribute(CharTermAttribute.class);
    final OffsetAttribute offsetAtt=ts.addAttribute(OffsetAttribute.class);
    String lastToken=null;
    query=new BooleanQuery.Builder();
    int maxEndOffset=-1;
    matchedTokens=new HashSet<>();
    while (ts.incrementToken()) {
      if (lastToken != null) {
        matchedTokens.add(lastToken);
        query.add(new TermQuery(new Term(TEXT_FIELD_NAME,lastToken)),occur);
      }
      lastToken=termAtt.toString();
      if (lastToken != null) {
        maxEndOffset=Math.max(maxEndOffset,offsetAtt.endOffset());
      }
    }
    ts.end();
    if (lastToken != null) {
      Query lastQuery;
      if (maxEndOffset == offsetAtt.endOffset()) {
        lastQuery=getLastTokenQuery(lastToken);
        prefixToken=lastToken;
      }
 else {
        matchedTokens.add(lastToken);
        lastQuery=new TermQuery(new Term(TEXT_FIELD_NAME,lastToken));
      }
      if (lastQuery != null) {
        query.add(lastQuery,occur);
      }
    }
    if (contextQuery != null) {
      boolean allMustNot=true;
      for (      BooleanClause clause : contextQuery.clauses()) {
        if (clause.getOccur() != BooleanClause.Occur.MUST_NOT) {
          allMustNot=false;
          break;
        }
      }
      if (allMustNot) {
        for (        BooleanClause clause : contextQuery.clauses()) {
          query.add(clause);
        }
      }
 else       if (allTermsRequired == false) {
        BooleanQuery.Builder newQuery=new BooleanQuery.Builder();
        newQuery.add(query.build(),BooleanClause.Occur.MUST);
        newQuery.add(contextQuery,BooleanClause.Occur.MUST);
        query=newQuery;
      }
 else {
        query.add(contextQuery,BooleanClause.Occur.MUST);
      }
    }
  }
   Query finalQuery=finishQuery(query,allTermsRequired);
  TopFieldCollector c=TopFieldCollector.create(SORT,num,true,false,false);
  Collector c2=new EarlyTerminatingSortingCollector(c,SORT,num);
  List<LookupResult> results=null;
  IndexSearcher searcher=searcherMgr.acquire();
  try {
    searcher.search(finalQuery,c2);
    TopFieldDocs hits=c.topDocs();
    results=createResults(searcher,hits,num,key,doHighlight,matchedTokens,prefixToken);
  }
  finally {
    searcherMgr.release(searcher);
  }
  return results;
}

public List < LookupResult > lookup ( CharSequence key , BooleanQuery contextQuery , int num , boolean allTermsRequired , boolean doHighlight ) throws IOException { if ( searcherMgr == null ) { throw new IllegalStateException ( "suggester was not built" ) ; } final BooleanClause . Occur occur ; if ( allTermsRequired ) { occur = BooleanClause . Occur . MUST ; } else { occur = BooleanClause . Occur . SHOULD ; } BooleanQuery . Builder query ; Set < String > matchedTokens ; String prefixToken = null ; try ( TokenStream ts = queryAnalyzer . tokenStream ( "" , new StringReader ( key . toString ( ) ) ) ) { ts . reset ( ) ; final CharTermAttribute termAtt = ts . addAttribute ( CharTermAttribute . class ) ; final OffsetAttribute offsetAtt = ts . addAttribute ( OffsetAttribute . class ) ; String lastToken = null ; query = new BooleanQuery . Builder ( ) ; int maxEndOffset = - 1 ; matchedTokens = new HashSet < > ( ) ; while ( ts . incrementToken ( ) ) { if ( lastToken != null ) { matchedTokens . add ( lastToken ) ; query . add ( new TermQuery ( new Term ( TEXT_FIELD_NAME , lastToken ) ) , occur ) ; } lastToken = termAtt . toString ( ) ; if ( lastToken != null ) { maxEndOffset = Math . max ( maxEndOffset , offsetAtt . endOffset ( ) ) ; } } ts . end ( ) ; if ( lastToken != null ) { Query lastQuery ; if ( maxEndOffset == offsetAtt . endOffset ( ) ) { lastQuery = getLastTokenQuery ( lastToken ) ; prefixToken = lastToken ; } else { matchedTokens . add ( lastToken ) ; lastQuery = new TermQuery ( new Term ( TEXT_FIELD_NAME , lastToken ) ) ; } if ( lastQuery != null ) { query . add ( lastQuery , occur ) ; } } if ( contextQuery != null ) { boolean allMustNot = true ; for ( BooleanClause clause : contextQuery . clauses ( ) ) { if ( clause . getOccur ( ) != BooleanClause . Occur . MUST_NOT ) { allMustNot = false ; break ; } } if ( allMustNot ) { for ( BooleanClause clause : contextQuery . clauses ( ) ) { query . add ( clause ) ; } } else if ( allTermsRequired == false ) { BooleanQuery . Builder newQuery = new BooleanQuery . Builder ( ) ; newQuery . add ( query . build ( ) , BooleanClause . Occur . MUST ) ; newQuery . add ( contextQuery , BooleanClause . Occur . MUST ) ; query = newQuery ; } else { query . add ( contextQuery , BooleanClause . Occur . MUST ) ; } } } Query finalQuery = finishQuery ( query , allTermsRequired ) ; TopFieldCollector c = TopFieldCollector . create ( SORT , num , true , false , false ) ; Collector c2 = new EarlyTerminatingSortingCollector ( c , SORT , num ) ; List < LookupResult > results = null ; IndexSearcher searcher = searcherMgr . acquire ( ) ; try { searcher . search ( finalQuery , c2 ) ; TopFieldDocs hits = c . topDocs ( ) ; results = createResults ( searcher , hits , num , key , doHighlight , matchedTokens , prefixToken ) ; } finally { searcherMgr . release ( searcher ) ; } return results ; }
this is an advanced method providing the capability to send down to the suggester any arbitrary lucene query to be used to filter the result of the suggester
