2013-07-08 63 views

回答

3

所以,我编译了我的代码与Lucene 4.5.1,它的工作原理。我已经使用它的扩展字段项查询“跨越第一”的查询,像这样被

package test; 

import java.io.IOException; 
import java.io.StringReader; 
import java.util.LinkedList; 
import java.util.List; 

import org.apache.lucene.analysis.Analyzer; 
import org.apache.lucene.analysis.TokenStream; 
import org.apache.lucene.analysis.standard.StandardAnalyzer; 
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; 
import org.apache.lucene.index.Term; 
import org.apache.lucene.queryparser.classic.ParseException; 
import org.apache.lucene.queryparser.classic.QueryParser; 
import org.apache.lucene.queryparser.ext.ExtendableQueryParser; 
import org.apache.lucene.queryparser.ext.ExtensionQuery; 
import org.apache.lucene.queryparser.ext.Extensions; 
import org.apache.lucene.queryparser.ext.ParserExtension; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.spans.SpanFirstQuery; 
import org.apache.lucene.search.spans.SpanNearQuery; 
import org.apache.lucene.search.spans.SpanQuery; 
import org.apache.lucene.search.spans.SpanTermQuery; 
import org.apache.lucene.util.Version; 

public class ExpandableQueryParserTest { 

    private static Extensions createExtensions() { 

     ParserExtension parserExtension = new ParserExtension() { 

      @Override 
      public Query parse(final ExtensionQuery query) throws ParseException { 

       QueryParser parser = query.getTopLevelParser(); 
       // Although Analyzer implements java.io.Closeable, don't use it in try-with-resources. 
       // Otherwise, it won't be able to parse the rest of the query... 
       Analyzer analyzer = parser.getAnalyzer(); 
       String rawQueryString = query.getRawQueryString(); 

       List<SpanQuery> spans = new LinkedList<>(); 
       try (TokenStream stream = analyzer.tokenStream(query.getField(), new StringReader(rawQueryString))) { 

        stream.reset(); 

        while (stream.incrementToken()) { 
         String term = stream.getAttribute(CharTermAttribute.class).toString(); 
         spans.add(new SpanTermQuery(new Term(query.getField(), term))); 
        } 

        stream.close(); 

       } catch (IOException e) { 
        // Shouldn't happen as it's being read from RAM. 
        throw new ParseException(e.getMessage()); 
       } 

       SpanQuery[] spansArray = spans.toArray(new SpanQuery[spans.size()]); 
       SpanNearQuery spanNear = new SpanNearQuery(spansArray, 1, true, true); 
       return new SpanFirstQuery(spanNear, 1); 
      } 
     }; 

     Extensions extensions = new Extensions('_'); 
     extensions.add("spanfirst", parserExtension); 
     return extensions; 
    } 

    public static void main(String[] args) throws Exception { 

     // Be careful: QueryParser is not thread-safe. 
     QueryParser queryParser = new ExtendableQueryParser(Version.LUCENE_45, "", new StandardAnalyzer(Version.LUCENE_45), createExtensions()); 
     Query query = queryParser.parse("_spanfirst:hello"); 

     // prints "spanFirst(spanNear([hello], 1, true), 1)" 
     System.out.println(query); 

     queryParser = new ExtendableQueryParser(Version.LUCENE_45, "text", new StandardAnalyzer(Version.LUCENE_45), createExtensions()); 
     query = queryParser.parse("_spanfirst:hello"); 

     // prints "spanFirst(spanNear([text:hello], 1, true), 1)" 
     System.out.println(query); 

     queryParser = new ExtendableQueryParser(Version.LUCENE_45, "text", new StandardAnalyzer(Version.LUCENE_45), createExtensions()); 
     query = queryParser.parse("hello"); 

     // prints "text:hello" 
     System.out.println(query); 

    } 
} 

当然,你可以用任何你需要扩展它。

问候。