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 } |