Mercurial Hosting > luan
comparison src/goodjava/lucene/queryparser/StringFieldParser.java @ 1458:6b6c11c9164e
goodjava.lucene
| author | Franklin Schmidt <fschmidt@gmail.com> |
|---|---|
| date | Fri, 20 Mar 2020 10:58:53 -0600 |
| parents | src/goodjava/queryparser/StringFieldParser.java@f6075d7a36f2 |
| children | b04b8fc5f4f4 |
comparison
equal
deleted
inserted
replaced
| 1457:a84ce37f3892 | 1458:6b6c11c9164e |
|---|---|
| 1 package goodjava.lucene.queryparser; | |
| 2 | |
| 3 import java.io.StringReader; | |
| 4 import java.io.IOException; | |
| 5 import org.apache.lucene.analysis.Analyzer; | |
| 6 import org.apache.lucene.analysis.TokenStream; | |
| 7 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; | |
| 8 import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; | |
| 9 import org.apache.lucene.search.Query; | |
| 10 import org.apache.lucene.search.TermQuery; | |
| 11 import org.apache.lucene.search.TermRangeQuery; | |
| 12 import org.apache.lucene.search.PhraseQuery; | |
| 13 import org.apache.lucene.search.WildcardQuery; | |
| 14 import org.apache.lucene.search.PrefixQuery; | |
| 15 import org.apache.lucene.search.SortField; | |
| 16 import org.apache.lucene.index.Term; | |
| 17 import goodjava.parser.ParseException; | |
| 18 | |
| 19 | |
| 20 public class StringFieldParser implements FieldParser { | |
| 21 public int slop = 0; | |
| 22 public final Analyzer analyzer; | |
| 23 | |
| 24 public StringFieldParser(Analyzer analyzer) { | |
| 25 this.analyzer = analyzer; | |
| 26 } | |
| 27 | |
| 28 @Override public Query getQuery(SaneQueryParser qp,String field,String query) throws ParseException { | |
| 29 String wildcard = wildcard(qp,query); | |
| 30 if( wildcard != null ) | |
| 31 return new WildcardQuery(new Term(field,wildcard)); | |
| 32 if( query.endsWith("*") && !query.endsWith("\\*") ) | |
| 33 return new PrefixQuery(new Term(field,query.substring(0,query.length()-1))); | |
| 34 query = escape(qp,query); | |
| 35 PhraseQuery pq = new PhraseQuery(); | |
| 36 try { | |
| 37 TokenStream ts = analyzer.tokenStream(field,new StringReader(query)); | |
| 38 CharTermAttribute termAttr = ts.addAttribute(CharTermAttribute.class); | |
| 39 PositionIncrementAttribute posAttr = ts.addAttribute(PositionIncrementAttribute.class); | |
| 40 ts.reset(); | |
| 41 int pos = -1; | |
| 42 while( ts.incrementToken() ) { | |
| 43 pos += posAttr.getPositionIncrement(); | |
| 44 pq.add( new Term(field,termAttr.toString()), pos ); | |
| 45 } | |
| 46 ts.end(); | |
| 47 ts.close(); | |
| 48 } catch(IOException e) { | |
| 49 throw new RuntimeException(e); | |
| 50 } | |
| 51 Term[] terms = pq.getTerms(); | |
| 52 if( terms.length==1 && pq.getPositions()[0]==0 ) | |
| 53 return new TermQuery(terms[0]); | |
| 54 return pq; | |
| 55 } | |
| 56 | |
| 57 @Override public Query getRangeQuery(SaneQueryParser qp,String field,String minQuery,String maxQuery,boolean includeMin,boolean includeMax) throws ParseException { | |
| 58 minQuery = minQuery.equals("*") ? null : escape(qp,minQuery); | |
| 59 maxQuery = maxQuery.equals("*") ? null : escape(qp,maxQuery); | |
| 60 return TermRangeQuery.newStringRange(field,minQuery,maxQuery,includeMin,includeMax); | |
| 61 } | |
| 62 | |
| 63 static String escape(SaneQueryParser qp,String s) throws ParseException { | |
| 64 final char[] a = s.toCharArray(); | |
| 65 int i, n; | |
| 66 if( a[0] == '"' ) { | |
| 67 if( a[a.length-1] != '"' ) throw new RuntimeException(); | |
| 68 i = 1; | |
| 69 n = a.length - 1; | |
| 70 } else { | |
| 71 i = 0; | |
| 72 n = a.length; | |
| 73 } | |
| 74 StringBuilder sb = new StringBuilder(); | |
| 75 for( ; i<n; i++ ) { | |
| 76 char c = a[i]; | |
| 77 if( c == '\\' ) { | |
| 78 if( ++i == a.length ) | |
| 79 throw qp.exception("ends with '\\'"); | |
| 80 c = a[i]; | |
| 81 } | |
| 82 sb.append(c); | |
| 83 } | |
| 84 return sb.toString(); | |
| 85 } | |
| 86 | |
| 87 private static String wildcard(SaneQueryParser qp,String s) throws ParseException { | |
| 88 final char[] a = s.toCharArray(); | |
| 89 if( a[0] == '"' ) | |
| 90 return null; | |
| 91 boolean hasWildcard = false; | |
| 92 StringBuilder sb = new StringBuilder(); | |
| 93 for( int i=0; i<a.length; i++ ) { | |
| 94 char c = a[i]; | |
| 95 if( c=='?' || c=='*' && i<a.length-1 ) | |
| 96 hasWildcard = true; | |
| 97 if( c == '\\' ) { | |
| 98 if( ++i == a.length ) | |
| 99 throw qp.exception("ends with '\\'"); | |
| 100 c = a[i]; | |
| 101 if( c=='?' || c=='*' ) | |
| 102 sb.append('\\'); | |
| 103 } | |
| 104 sb.append(c); | |
| 105 } | |
| 106 return hasWildcard ? sb.toString() : null; | |
| 107 } | |
| 108 | |
| 109 @Override public SortField getSortField(SaneQueryParser qp,String field,boolean reverse) { | |
| 110 return new SortField( field, SortField.Type.STRING, reverse ); | |
| 111 } | |
| 112 | |
| 113 } |
