comparison lucene/src/luan/modules/lucene/queryparser/StringFieldParser.java @ 730:01e68da6983b

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