下面列出了怎么用org.apache.lucene.search.Filter的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
protected Filter construct(LindenFilter lindenFilter, LindenConfig config) throws Exception {
List<LindenBooleanSubFilter> booleanSubFilterList = lindenFilter.getBooleanFilter().getFilters();
BooleanFilter booleanFilter = new BooleanFilter();
for (LindenBooleanSubFilter booleanSubFilter : booleanSubFilterList) {
LindenFilter subFilter = booleanSubFilter.getFilter();
switch (booleanSubFilter.clause) {
case MUST:
booleanFilter.add(FilterConstructor.constructFilter(subFilter, config), BooleanClause.Occur.MUST);
continue;
case SHOULD:
booleanFilter.add(FilterConstructor.constructFilter(subFilter, config), BooleanClause.Occur.SHOULD);
continue;
case MUST_NOT:
booleanFilter.add(FilterConstructor.constructFilter(subFilter, config), BooleanClause.Occur.MUST_NOT);
}
}
return booleanFilter;
}
public static Filter constructFilter(LindenFilter lindenFilter, LindenConfig config) throws Exception {
if (lindenFilter == null) {
return null;
}
if (lindenFilter.isSetTermFilter()) {
return TERM_FILTER_CONSTRUCTOR.construct(lindenFilter, config);
} else if (lindenFilter.isSetRangeFilter()) {
return RANGE_FILTER_CONSTRUCTOR.construct(lindenFilter, config);
} else if (lindenFilter.isSetQueryFilter()) {
return QUERY_FILTER_CONSTRUCTOR.construct(lindenFilter, config);
} else if (lindenFilter.isSetBooleanFilter()) {
return BOOLEAN_FILTER_CONSTRUCTOR.construct(lindenFilter, config);
} else if (lindenFilter.isSetSpatialFilter()) {
return SPATIAL_FILTER_CONSTRUCTOR.construct(lindenFilter, config);
} else if (lindenFilter.isSetNotNullFieldFilter()) {
return NOT_NULL_FIELD_FILTER_CONSTRUCTOR.construct(lindenFilter, config);
}
return null;
}
/**
* Returns a list of location near a certain coordinate.
* @param latitude, @param longitude - Center of search area
* @param distanceInMiles - Search Radius in miles
* @param indexerPath - Path to Lucene index
* @param count - Upper bound to number of results
* @return - List of locations sorted by population
* @throws IOException
*/
public List<Location> searchNearby(Double latitude, Double longitude, Double distanceInMiles, String indexerPath, int count) throws IOException {
double distanceInDeg = DistanceUtils.dist2Degrees(distanceInMiles,DistanceUtils.EARTH_EQUATORIAL_RADIUS_MI);
SpatialArgs spatialArgs = new SpatialArgs(SpatialOperation.IsWithin,
ctx.makeCircle(longitude,latitude, distanceInDeg));
String key = latitude+"-"+longitude;
Filter filter = strategy.makeFilter(spatialArgs);
IndexSearcher searcher = new IndexSearcher(createIndexReader(indexerPath));
Sort sort = new Sort(populationSort);
TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), filter, count, sort);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
HashMap<String, List<Location>> allCandidates = new HashMap<String, List<Location>>();
getMatchingCandidates(searcher, allCandidates, key, scoreDocs);
List<Location> results = allCandidates.get(key);
return results;
}
@Nullable
protected Filter toFilter(@Nullable Iterable<String> groups) {
final Iterator<String> i = groups != null ? groups.iterator() : null;
final Filter result;
if (i != null && i.hasNext()) {
final Filter first = new TermFilter(new Term("group", i.next()));
if (i.hasNext()) {
final List<Filter> filters = new ArrayList<>();
filters.add(first);
while (i.hasNext()) {
filters.add(new TermFilter(new Term("group", i.next())));
}
result = new ChainedFilter(filters.toArray(new Filter[filters.size()]), OR);
} else {
result = first;
}
} else {
result = null;
}
return result;
}
private Filter buildNewFilter(Query query, ConcurrentMap<String, String> filterAlias, FilterParser filterParser)
throws ParseException {
if (query instanceof BooleanQuery) {
BooleanQuery booleanQuery = (BooleanQuery) query;
BooleanFilter booleanFilter = new BooleanFilter();
for (BooleanClause clause : booleanQuery.clauses()) {
booleanFilter.add(buildNewFilter(clause.getQuery(), filterAlias, filterParser), clause.getOccur());
}
return booleanFilter;
} else if (query instanceof TermQuery) {
TermQuery termQuery = (TermQuery) query;
Term term = termQuery.getTerm();
String key = term.toString();
String queryStr = filterAlias.get(key);
if (queryStr == null) {
return new QueryWrapperFilter(termQuery);
}
String id = getId(key);
return new FilterCache(id, new QueryWrapperFilter(filterParser.parse(queryStr)));
} else {
return new QueryWrapperFilter(query);
}
}
private Query getHighlightQuery(Selector selector, String table, FieldManager fieldManager) throws ParseException,
BlurException {
HighlightOptions highlightOptions = selector.getHighlightOptions();
if (highlightOptions == null) {
return null;
}
org.apache.blur.thrift.generated.Query query = highlightOptions.getQuery();
if (query == null) {
return null;
}
TableContext context = getTableContext(table);
Filter preFilter = QueryParserUtil.parseFilter(table, query.recordFilter, false, fieldManager, _filterCache,
context);
Filter postFilter = QueryParserUtil.parseFilter(table, query.rowFilter, true, fieldManager, _filterCache, context);
return QueryParserUtil.parseQuery(query.query, query.rowQuery, fieldManager, postFilter, preFilter,
getScoreType(query.scoreType), context);
}
/**
* This method is very important!!! It handles rewriting the real query (which
* can be a {@link SuperQuery} to have document (record) level filtering or
* access control.
*/
@Override
protected Query wrapFilter(Query query, Filter filter) {
if (filter == null) {
return query;
} else if (query instanceof SuperQuery) {
SuperQuery superQuery = (SuperQuery) query;
Query innerQuery = superQuery.getQuery();
Term primeDocTerm = superQuery.getPrimeDocTerm();
ScoreType scoreType = superQuery.getScoreType();
return new SuperQuery(wrapFilter(innerQuery, filter), scoreType, primeDocTerm);
} else if (query instanceof BooleanQuery) {
BooleanQuery booleanQuery = (BooleanQuery) query;
List<BooleanClause> clauses = booleanQuery.clauses();
for (BooleanClause booleanClause : clauses) {
booleanClause.setQuery(wrapFilter(booleanClause.getQuery(), filter));
}
return booleanQuery;
} else {
return new FilteredQuery(query, filter);
}
}
@Test
public void testFetchRowByRecordIdWithFilterNoHit() throws Exception {
IndexManagerTestReadInterceptor.interceptor = new ReadInterceptor(null) {
@Override
public Filter getFilter() {
return new QueryWrapperFilter(new TermQuery(new Term(FAMILY + ".testcol1", "NOHIT")));
}
};
Selector selector = new Selector().setRowId("row-1").setRecordId("record-1").setRecordOnly(true);
FetchResult fetchResult = new FetchResult();
indexManager.fetchRow(TABLE, selector, fetchResult);
assertFalse(fetchResult.deleted);
assertFalse(fetchResult.exists);
assertEquals(TABLE, fetchResult.table);
assertNull(fetchResult.rowResult);
assertNull(fetchResult.recordResult);
}
@Override
public Filter makeFilter(SpatialArgs args) {
final SpatialOperation op = args.getOperation();
if (op != SpatialOperation.Intersects)
throw new UnsupportedSpatialOperation(op);
Shape shape = args.getShape();
int detailLevel = grid.getLevelForDistance(args.resolveDistErr(ctx, distErrPct));
List<Cell> cells = grid.getCells(shape, detailLevel, false,// no parents
true);// simplify
BytesRef[] terms = new BytesRef[cells.size()];
int i = 0;
for (Cell cell : cells) {
terms[i++] = new BytesRef(cell.getTokenString());
}
return new TermsFilter(getFieldName(), terms);
}
public ChildrenQuery(ParentChildIndexFieldData ifd, String parentType, String childType, Filter parentFilter, Query childQuery, ScoreType scoreType, int minChildren, int maxChildren, int shortCircuitParentDocSet, BitSetProducer nonNestedDocsFilter) {
this.ifd = ifd;
this.parentType = parentType;
this.childType = childType;
this.parentFilter = parentFilter;
this.childQuery = childQuery;
this.scoreType = scoreType;
this.shortCircuitParentDocSet = shortCircuitParentDocSet;
this.nonNestedDocsFilter = nonNestedDocsFilter;
assert maxChildren == 0 || minChildren <= maxChildren;
this.minChildren = minChildren > 1 ? minChildren : 0;
this.maxChildren = maxChildren;
}
protected ParentWeight(Query query, Weight childWeight, Filter parentFilter, long remaining, ParentCollector collector, int minChildren, int maxChildren) {
super(query);
this.childWeight = childWeight;
this.parentFilter = parentFilter;
this.remaining = remaining;
this.collector = collector;
this.minChildren = minChildren;
this.maxChildren = maxChildren;
}
private ChildWeight(Query query, Weight parentWeight, Filter childrenFilter, ParentOrdAndScoreCollector collector, IndexParentChildFieldData globalIfd) {
super(query);
this.parentWeight = parentWeight;
this.childrenFilter = childrenFilter;
this.parentIdxs = collector.parentIdxs;
this.scores = collector.scores;
this.globalIfd = globalIfd;
}
public ChildrenConstantScoreQuery(IndexParentChildFieldData parentChildIndexFieldData, Query childQuery, String parentType, String childType, Filter parentFilter, int shortCircuitParentDocSet, BitSetProducer nonNestedDocsFilter) {
this.parentChildIndexFieldData = parentChildIndexFieldData;
this.parentFilter = parentFilter;
this.parentType = parentType;
this.childType = childType;
this.childQuery = childQuery;
this.shortCircuitParentDocSet = shortCircuitParentDocSet;
this.nonNestedDocsFilter = nonNestedDocsFilter;
}
@Override
public Weight doCreateWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
SearchContext sc = SearchContext.current();
IndexParentChildFieldData globalIfd = parentChildIndexFieldData.loadGlobal((DirectoryReader)searcher.getIndexReader());
final long valueCount;
List<LeafReaderContext> leaves = searcher.getIndexReader().leaves();
if (globalIfd == null || leaves.isEmpty()) {
return new BooleanQuery.Builder().build().createWeight(searcher, needsScores);
} else {
AtomicParentChildFieldData afd = globalIfd.load(leaves.get(0));
SortedDocValues globalValues = afd.getOrdinalsValues(parentType);
valueCount = globalValues.getValueCount();
}
if (valueCount == 0) {
return new BooleanQuery.Builder().build().createWeight(searcher, needsScores);
}
ParentOrdCollector collector = new ParentOrdCollector(globalIfd, valueCount, parentType);
searcher.search(childQuery, collector);
final long remaining = collector.foundParents();
if (remaining == 0) {
return new BooleanQuery.Builder().build().createWeight(searcher, needsScores);
}
Filter shortCircuitFilter = null;
if (remaining <= shortCircuitParentDocSet) {
shortCircuitFilter = ParentIdsFilter.createShortCircuitFilter(
nonNestedDocsFilter, sc, parentType, collector.values, collector.parentOrds, remaining
);
}
return new ParentWeight(this, parentFilter, globalIfd, shortCircuitFilter, collector, remaining);
}
public ParentWeight(Query query, Filter parentFilter, IndexParentChildFieldData globalIfd, Filter shortCircuitFilter, ParentOrdCollector collector, long remaining) {
super(query);
this.parentFilter = parentFilter;
this.globalIfd = globalIfd;
this.shortCircuitFilter = shortCircuitFilter;
this.collector = collector;
this.remaining = remaining;
}
public LindenResultParser(LindenConfig config, LindenSearchRequest request,
IndexSearcher indexSearcher, LindenSnippetGenerator snippetGenerator, Query query,
Filter filter, Sort sort) {
this.config = config;
this.request = request;
this.indexSearcher = indexSearcher;
this.snippetGenerator = snippetGenerator;
this.query = query;
this.filter = filter;
this.sort = sort;
this.sortScoreFieldPos = getSortScoreFieldPos(sort);
this.leaves = indexSearcher.getIndexReader().leaves();
}
@Override
protected Filter construct(LindenFilter lindenFilter, LindenConfig config) throws Exception {
LindenNotNullFieldFilter lindenNotNullFieldFilter = lindenFilter.getNotNullFieldFilter();
NotNullFieldFilter notNullFieldFilter = new NotNullFieldFilter(lindenNotNullFieldFilter.getField());
if (!lindenNotNullFieldFilter.isReverse()) {
return notNullFieldFilter;
}
BooleanFilter booleanFilter = new BooleanFilter();
booleanFilter.add(notNullFieldFilter, BooleanClause.Occur.MUST_NOT);
return booleanFilter;
}
@Override
protected Filter construct(LindenFilter lindenFilter, LindenConfig config) throws IOException {
LindenSpatialFilter spatialFilter = lindenFilter.getSpatialFilter();
SpatialArgs spatialArgs = new SpatialArgs(
SpatialOperation.Intersects,
spatialContext.makeCircle(
spatialFilter.getSpatialParam().coordinate.getLongitude(),
spatialFilter.getSpatialParam().coordinate.getLatitude(),
DistanceUtils
.dist2Degrees(spatialFilter.getSpatialParam().getDistanceRange(), DistanceUtils.EARTH_MEAN_RADIUS_KM)));
return spatialStrategy.makeFilter(spatialArgs);
}
@Override
protected Filter construct(LindenFilter lindenFilter, LindenConfig config) throws IOException {
LindenRangeFilter lindenRangeFilter = lindenFilter.getRangeFilter();
LindenRange range = lindenRangeFilter.getRange();
LindenType type = range.getType();
String start = range.getStartValue();
String end = range.getEndValue();
String fieldName = range.getField();
boolean startClose = range.isStartClosed();
boolean endClose = range.isEndClosed();
Filter filter = null;
switch (type) {
case STRING:
case FACET:
filter = new TermRangeFilter(fieldName, bytesRefVal(start), bytesRefVal(end), startClose, endClose);
break;
case INTEGER:
filter = NumericRangeFilter.newIntRange(fieldName, intVal(start), intVal(end), startClose, endClose);
break;
case LONG:
filter = NumericRangeFilter.newLongRange(fieldName, longVal(start), longVal(end), startClose, endClose);
break;
case DOUBLE:
filter = NumericRangeFilter.newDoubleRange(fieldName, doubleVal(start), doubleVal(end), startClose, endClose);
break;
case FLOAT:
filter = NumericRangeFilter.newFloatRange(fieldName, floatVal(start), floatVal(end), startClose, endClose);
break;
}
return filter;
}
@Test
public void testFlexibleFilter() throws Exception {
String bql = "select name from linden where flexible_query is 'qq音乐' full_match in (name^1.5) \n"
+ "USING MODEL test \n"
+ "begin\n"
+ " return score();\n"
+ "end\n"
+ "order by score,id limit $offset, $length source";
LindenSearchRequest request = bqlCompiler.compile(bql).getSearchRequest();
Filter filter = FilterConstructor.constructFilter(request.getFilter(), lindenConfig);
Assert.assertEquals("QueryWrapperFilter(FlexibleQuery([name^1.5]:[qq,音,乐]fullMatch))", filter.toString());
bql = "select name from linden \n"
+ "by flexible_query is \"lucene\" in (title^1.2) \n"
+ "USING MODEL test1 \n"
+ "begin \n"
+ " return score() + 1;\n"
+ "end\n"
+ "where flexible_query is 'ddd' full_match in (field1)\n"
+ "USING MODEL filter_func begin return 1f; end \n"
+ "order by score,id limit $offset, $length source";
request = bqlCompiler.compile(bql).getSearchRequest();
LindenResult result = lindenCore.search(request);
Assert.assertEquals(1, result.getHitsSize());
Assert.assertEquals(1f, result.getHits().get(0).getScore(), DELTA5);
Assert.assertEquals("4", result.getHits().get(0).getId());
}
public List<Course> getCourses(String query) {
try {
List<Course> qlist = new ArrayList<Course>();
IndexSearcher indexSearcher = new IndexSearcher(INDEXPATH);
long begin = new Date().getTime();
//下面的是进行title,content 两个范围内进行收索. SHOULD 表示OR
BooleanClause.Occur[] clauses = {BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD};
Query queryOBJ = MultiFieldQueryParser.parse(query, new String[]{"courseIntro", "courseTitle"}, clauses, new StandardAnalyzer());//parser.parse(query);
Filter filter = null;
//################# 搜索相似度最高的记录 ###################
TopDocs topDocs = indexSearcher.search(queryOBJ, filter, 1000);
Course course = null;
//输出结果
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document targetDoc = indexSearcher.doc(scoreDoc.doc);
course = new Course();
String courseIntro = targetDoc.get("courseIntro");
String courseTitle = targetDoc.get("courseTitle");
String courseId = targetDoc.get("courseId");
TokenStream contentTokenStream = analyzer.tokenStream("courseIntro", new StringReader(courseIntro));
TokenStream titleTokenStream = analyzer.tokenStream("courseTitle", new StringReader(courseTitle));
course.setCourseIntro(courseIntro);
course.setCourseTitle(courseTitle);
course.setCourseId(courseId);
course.setType(targetDoc.get("type"));
course.setCourseState(targetDoc.get("courseState"));
qlist.add(course);
}
indexSearcher.close();
return qlist;
} catch (Exception e) {
logger.error("getCourses error.");
return null;
}
}
@Override
public Filter convertToLuceneSearchFilter(@Nonnull UserProfileDataFilter filter) {
final BooleanFilter result = new BooleanFilter();
final Filter include = toFilter(filter.getIncludingGroups());
if (include != null) {
result.add(include, MUST);
}
final Filter exclude = toFilter(filter.getExcludingGroups());
if (exclude != null) {
result.add(exclude, MUST_NOT);
}
return result;
}
public QueryContext(OCommandContext context, IndexSearcher searcher, Query query, Filter filter, Sort sort) {
this.context = context;
this.searcher = searcher;
this.query = query;
this.filter = filter;
this.sort = sort;
initCFG();
}
public AliasBlurFilterCache(BlurConfiguration configuration) {
super(configuration);
long _cacheEntries = 100;
_preFilterCacheMap = new ConcurrentLinkedHashMap.Builder<FilterKey, Filter>()
.maximumWeightedCapacity(_cacheEntries).build();
_postFilterCacheMap = new ConcurrentLinkedHashMap.Builder<FilterKey, Filter>().maximumWeightedCapacity(
_cacheEntries).build();
Map<String, String> properties = configuration.getProperties();
for (Entry<String, String> entry : properties.entrySet()) {
if (isFilterAlias(entry.getKey())) {
String value = entry.getValue();
if (value == null || value.isEmpty()) {
continue;
}
String name = getFilterAlias(entry.getKey());
int index = name.indexOf('.');
String table = name.substring(0, index);
String alias = name.substring(index + 1);
ConcurrentMap<String, String> aliasFilterMap = _tableAliasFilterMap.get(table);
if (aliasFilterMap == null) {
aliasFilterMap = new ConcurrentHashMap<String, String>();
_tableAliasFilterMap.put(table, aliasFilterMap);
}
aliasFilterMap.put(alias, value);
}
}
}
@Override
public Filter storePreFilter(String table, String filterStr, Filter filter, FilterParser filterParser)
throws ParseException {
if (filter instanceof QueryWrapperFilter) {
QueryWrapperFilter queryWrapperFilter = (QueryWrapperFilter) filter;
Query query = queryWrapperFilter.getQuery();
Filter newFilter = buildNewFilter(query, _tableAliasFilterMap.get(table), filterParser);
FilterKey key = new FilterKey(table, filterStr);
_preFilterCacheMap.put(key, newFilter);
return newFilter;
}
return filter;
}
public String parseQuery(String table, org.apache.blur.thrift.generated.Query simpleQuery) throws ParseException,
BlurException {
TableContext context = getTableContext(table);
FieldManager fieldManager = context.getFieldManager();
Filter preFilter = QueryParserUtil.parseFilter(table, simpleQuery.recordFilter, false, fieldManager, _filterCache,
context);
Filter postFilter = QueryParserUtil.parseFilter(table, simpleQuery.rowFilter, true, fieldManager, _filterCache,
context);
Query userQuery = QueryParserUtil.parseQuery(simpleQuery.query, simpleQuery.rowQuery, fieldManager, postFilter,
preFilter, getScoreType(simpleQuery.scoreType), context);
return userQuery.toString();
}
private Query[] getFacetQueries(BlurQuery blurQuery, FieldManager fieldManager, TableContext context,
Filter postFilter, Filter preFilter) throws ParseException {
int size = blurQuery.facets.size();
Query[] queries = new Query[size];
for (int i = 0; i < size; i++) {
queries[i] = QueryParserUtil.parseQuery(blurQuery.facets.get(i).queryStr, blurQuery.query.rowQuery, fieldManager,
postFilter, preFilter, ScoreType.CONSTANT, context);
}
return queries;
}
@SuppressWarnings("unchecked")
private static boolean isFiltered(int notAdjustedDocId, IndexReader reader, Filter filter) throws IOException {
if (filter == null) {
return false;
}
if (reader instanceof BaseCompositeReader) {
BaseCompositeReader<IndexReader> indexReader = (BaseCompositeReader<IndexReader>) reader;
List<? extends IndexReader> sequentialSubReaders = BaseCompositeReaderUtil.getSequentialSubReaders(indexReader);
int readerIndex = BaseCompositeReaderUtil.readerIndex(indexReader, notAdjustedDocId);
int readerBase = BaseCompositeReaderUtil.readerBase(indexReader, readerIndex);
int docId = notAdjustedDocId - readerBase;
IndexReader orgReader = sequentialSubReaders.get(readerIndex);
SegmentReader sReader = AtomicReaderUtil.getSegmentReader(orgReader);
if (sReader != null) {
SegmentReader segmentReader = (SegmentReader) sReader;
DocIdSet docIdSet = filter.getDocIdSet(segmentReader.getContext(), segmentReader.getLiveDocs());
DocIdSetIterator iterator = docIdSet.iterator();
if (iterator == null) {
return true;
}
if (iterator.advance(docId) == docId) {
return false;
}
return true;
}
throw new RuntimeException("Reader has to be a SegmentReader [" + orgReader + "]");
} else {
throw new RuntimeException("Reader has to be a BaseCompositeReader [" + reader + "]");
}
}
public static Query parseQuery(String query, boolean superQueryOn, FieldManager fieldManager, Filter postFilter,
Filter preFilter, ScoreType scoreType, TableContext tableContext) throws ParseException {
Query result = new SuperParser(LUCENE_VERSION, fieldManager, superQueryOn, preFilter, scoreType,
tableContext.getDefaultPrimeDocTerm()).parse(query);
if (postFilter == null) {
return result;
}
return new FilteredQuery(result, postFilter);
}
private static OpenBitSet getDocsToFetch(AtomicReader atomicReader, Selector selector, int primeDocRowId,
int numberOfDocsInRow, Bits liveDocs, Filter filter, AtomicInteger totalRecords) throws IOException {
Set<String> alreadyProcessed = new HashSet<String>();
OpenBitSet bits = new OpenBitSet(numberOfDocsInRow);
OpenBitSet mask = null;
if (filter != null) {
DocIdSet docIdSet = filter.getDocIdSet(atomicReader.getContext(), liveDocs);
mask = getMask(docIdSet, primeDocRowId, numberOfDocsInRow);
}
Set<String> columnFamiliesToFetch = selector.getColumnFamiliesToFetch();
boolean fetchAll = true;
if (columnFamiliesToFetch != null) {
fetchAll = false;
applyFamilies(alreadyProcessed, bits, columnFamiliesToFetch, atomicReader, primeDocRowId, numberOfDocsInRow,
liveDocs);
}
Map<String, Set<String>> columnsToFetch = selector.getColumnsToFetch();
if (columnsToFetch != null) {
fetchAll = false;
applyColumns(alreadyProcessed, bits, columnsToFetch, atomicReader, primeDocRowId, numberOfDocsInRow, liveDocs);
}
if (fetchAll) {
bits.set(0, numberOfDocsInRow);
}
if (mask != null) {
bits.intersect(mask);
}
totalRecords.set((int) bits.cardinality());
return bits;
}