package net.ion.craken.node.crud; import java.io.IOException; import java.util.Iterator; import net.ion.craken.node.ReadNode; import net.ion.craken.node.ReadSession; import net.ion.craken.node.crud.tree.Fqn; import net.ion.framework.db.Page; import net.ion.framework.util.Debug; import net.ion.framework.util.ListUtil; import net.ion.framework.util.ObjectUtil; import net.ion.framework.util.StringUtil; import net.ion.nsearcher.common.IKeywordField; import net.ion.nsearcher.search.SearchRequest; import net.ion.nsearcher.search.SearchResponse; import net.ion.nsearcher.search.Searcher; import net.ion.nsearcher.search.filter.FilterUtil; import net.ion.nsearcher.search.filter.MatchAllDocsFilter; import net.ion.nsearcher.search.filter.TermFilter; import org.apache.ecs.xml.XML; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.search.Filter; import org.apache.lucene.search.Query; import org.apache.lucene.search.Sort; import com.google.common.base.Splitter; public class ChildQueryRequest { private ReadSession session; private SearchRequest request; protected ChildQueryRequest(ReadSession session, Query query, Searcher searcher) { this.session = session; this.request = searcher.createRequest(query).selections(IKeywordField.DocKey); } public static ChildQueryRequest create(ReadSession session, Searcher searcher, Query query) { return new ChildQueryRequest(session, query, searcher); } public ChildQueryRequest refTo(String refName, Fqn target) { filter(new TermFilter("@" + refName, target.toString())); return this; } public ChildQueryRequest in(String field, String... values) { if (values == null || values.length == 0) return this; filter(Filters.in(field, values)); return this; } public ChildQueryRequest between(String field, int min, int max) { return between(field, 1L * min, 1L * max); } public ChildQueryRequest between(String field, long min, long max) { filter(Filters.between(field, min, max)); return this; } public ChildQueryRequest between(String field, String minTerm, String maxTerm) { filter(Filters.between(field, minTerm, maxTerm)); return this; } public ChildQueryRequest lt(String field, int max) { return lt(field, 1L * max); } public ChildQueryRequest lt(String field, long max) { filter(Filters.lt(field, max)); return this; } public ChildQueryRequest lt(String field, String higherTerm) { filter(Filters.lt(field, higherTerm)); return this; } public ChildQueryRequest lt(String field, Object max) { if (max instanceof Long) { return lt(field, (Long) max); } else { return lt(field, ObjectUtil.toString(max)); } } public ChildQueryRequest lte(String field, String higherTerm) { filter(Filters.lte(field, higherTerm)); return this; } public ChildQueryRequest lte(String field, int max) { return lte(field, 1L * max); } public ChildQueryRequest lte(String field, long max) { filter(Filters.lte(field, max)); return this; } public ChildQueryRequest lte(String field, Object max) { if (max instanceof Long) { return lte(field, (Long) max); } else { return lte(field, ObjectUtil.toString(max)); } } public ChildQueryRequest gt(String field, int min) { return gt(field, 1L * min); } public ChildQueryRequest gt(String field, long min) { filter(Filters.gt(field, min)); return this; } public ChildQueryRequest gt(String field, String lowerTerm) { filter(Filters.gt(field, lowerTerm)); return this; } public ChildQueryRequest gt(String field, Object max) { if (max instanceof Long) { return gt(field, (Long) max); } else { return gt(field, ObjectUtil.toString(max)); } } public ChildQueryRequest gte(String field, String lowerTerm) { filter(Filters.gte(field, lowerTerm)); return this; } public ChildQueryRequest gte(String field, int min) { return gte(field, 1L * min); } public ChildQueryRequest gte(String field, long min) { filter(Filters.gte(field, min)); return this; } public ChildQueryRequest gte(String field, Object max) { if (max instanceof Long) { return gte(field, (Long) max); } else { return gte(field, ObjectUtil.toString(max)); } } public ChildQueryRequest eq(String field, Object value) { filter(Filters.eq(field, value)); return this; } public ChildQueryRequest ne(String field, String value) { filter(Filters.ne(field, value)); return this; } public ChildQueryRequest ne(String field, Object value) { filter(Filters.ne(field, ObjectUtil.toString(value))); return this; } public ChildQueryRequest where(String fnString) { if (StringUtil.isBlank(fnString)) return filter(new MatchAllDocsFilter()); filter(Filters.where(fnString)); return this; } public ChildQueryRequest wildcard(String field, Object value) { filter(Filters.wildcard(field, value)); return this; } public ChildQueryRequest query(String query) throws ParseException { filter(Filters.query(session.central().searchConfig(), session.central().indexConfig(), query)); return this; } public ChildQueryRequest skip(int skip) { request.skip(skip); return this; } public Query query() { return request.query(); } public ChildQueryRequest page(Page page) { this.skip(page.getStartLoc()).offset(page.getListNum()); return this; } public ChildQueryRequest offset(int offset) { request.offset(offset); return this; } public int skip() { return request.skip(); } public int offset() { return request.offset(); } public Sort sort() { return request.sort(); } public int limit() { return request.limit(); } public ChildQueryRequest ascending(String field) { request.ascending(field); return this; } public ChildQueryRequest descending(String field) { request.descending(field); return this; } public ChildQueryRequest ascendingNum(String field) { request.ascending(field + " _number"); return this; } public ChildQueryRequest descendingNum(String field) { request.descending(field + " _number"); return this; } public void setParam(String key, Object value) { request.setParam(key, value); } public Object getParam(String key) { return request.getParam(key); } public ChildQueryRequest filter(Filter... filters) { if (filters == null) return this; Filter compositeFilter = (request.getFilter() == null) ? FilterUtil.and(filters) : FilterUtil.and(request.getFilter(), FilterUtil.and(filters)); request.setFilter(compositeFilter); return this; } public Filter getFilter() { return request.getFilter(); } public ChildQueryResponse find() throws IOException { // field=asc && field2=desc... request.selections(IKeywordField.DocKey); try { final SearchResponse response = request.find() ; return ChildQueryResponse.create(session, response); } catch (ParseException ex) { throw new IOException(ex); } } public ReadNode findOne() throws IOException { return find().first(); } public SearchRequest request() { return request; } public XML toXML() { return request.toXML(); } public String toString() { return request.toString(); } public ChildQueryRequest sort(String sexpression) { Iterable<String> sorts = Splitter.on('&').trimResults().omitEmptyStrings().split(sexpression); Iterator<String> iter = sorts.iterator(); while (iter.hasNext()) { String[] exp = StringUtil.split(iter.next(), " ="); if (exp.length != 1 && exp.length != 2) throw new IllegalArgumentException("illegal sort expression : " + exp.toString()); if (exp.length == 1) { request.ascending(exp[0]); } else if (exp.length == 2) { request = ("desc".equalsIgnoreCase(exp[1])) ? request.descending(exp[0]) : request.ascending(exp[0]); } } return this; } }