0x00
level: 0x04
0x01
code:
package org.apache.lucene.demo.big.query; import java.io.IOException; import java.util.Comparator; import org.apache.lucene.index.FilteredTermsEnum; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.search.MultiTermQuery; import org.apache.lucene.util.AttributeSource; import org.apache.lucene.util.BytesRef; public class IpRangeQuery extends MultiTermQuery { private String minIp, maxIp; public IpRangeQuery(String field, String minIp, String maxIp) { super(field); this.minIp = minIp; this.maxIp = maxIp; } @Override protected TermsEnum getTermsEnum(Terms terms, AttributeSource atts) throws IOException { return new IpRangeTermsEnum(terms.iterator(null)); } private final class IpRangeTermsEnum extends FilteredTermsEnum { private Comparator<String> termComp = new Comparator<String>() { @Override public int compare(String ip1, String ip2) { if (ip1.equals(ip2)) return 0; return getIpLong(ip1) - getIpLong(ip2) > 0 ? 1 : -1; } }; private long getIpLong(String ip) { long v = 0; int startIndex = 0; int postion = 0; int vBase = 1; String ipByte = ""; for (int i = 0; i < 4; i++) { if (i == 3) { ipByte = ip.substring(startIndex, ip.length()); } else { postion = ip.indexOf(".", startIndex); ipByte = ip.substring(startIndex, postion); startIndex = postion + 1; } switch (i) { case 0: vBase = 1 * 1000 * 1000 * 1000; break; case 1: vBase = 1 * 1000 * 1000; break; case 2: vBase = 1 * 1000; break; default: vBase = 1; break; } v += Long.valueOf(ipByte) * vBase; } return v; } public IpRangeTermsEnum(TermsEnum tenum) { super(tenum); } @Override protected final BytesRef nextSeekTerm(BytesRef term) { String termStr = term == null ? null : term.utf8ToString(); if (termStr != null && termComp.compare(termStr, maxIp) > 0) return null; if (termStr != null && termComp.compare(minIp, termStr) > 0) return null; return term == null ? new BytesRef(minIp) : term; } @Override protected final AcceptStatus accept(BytesRef term) { String termStr = term.utf8ToString(); if (termComp.compare(termStr, minIp) < 0) return AcceptStatus.NO; if (termComp.compare(maxIp, termStr) < 0) return AcceptStatus.NO; return AcceptStatus.YES; } } @Override public String toString(String field) { return this.field + ":[" + this.minIp + " TO " + this.maxIp + "]"; } }
0x02
参考: TermRangeQuery 和 NumericRangeQuery