Elasticsearch 소스 분석 7 - Lucene 쿼리 인터페이스 범위 쿼리 호출
14902 단어 elasticsearchLucene
Elasticsearch 소스 분석 7 – Lucene 쿼리 인터페이스 범위 쿼리 호출
소개
범위 검색 특정 범위의 값이 일치하는 문서를 검색합니다.범위 조회는 최대 값과 최소 값을 포함하거나 포함하지 않을 수 있으며, 정렬은 사전 순서에 따라 정렬됩니다.범위 조회는 어떤 필드 값이 특정한 범위에 있는 문서를 찾을 수 있도록 합니다. 필드는 수치형일 수도 있고 문자열을 기반으로 할 수도 있습니다. (다른 아파치 루틴 조회에 비칠 수도 있습니다.)범위 조회는 단일 필드만 가능하며, 조회 매개 변수는 필드 이름에 봉인되어야 합니다.
질의 문법
예: year 필드에서 1700에서 1900까지의 모든 도서 찾기 {"query": {"range": {"year": {"gte": 1700, "lte": 1900}}}} 범위 조회는 다음 인자를 지원합니다.gte: 범위 조회는 필드 값이 이 매개 변수 값보다 크거나 같은 문서와 일치합니다.gt: 범위 조회는 이 매개 변수 값보다 필드 값이 큰 문서와 일치합니다.lte: 범위 조회는 필드 값이 이 매개 변수 값보다 작거나 같은 문서와 일치합니다.lt: 범위 조회는 필드 값이 이 매개 변수 값보다 작은 문서와 일치합니다.
원본 분석
'''(1)Elasticsearch code'''
public class RangeQueryParser implements QueryParser {
public static final String NAME = "range";
@Override
public Query parse(QueryParseContext parseContext) throws IOException, QueryParsingException {
XContentParser parser = parseContext.parser();
XContentParser.Token token = parser.nextToken();
if (token != XContentParser.Token.FIELD_NAME) {
throw new QueryParsingException(parseContext.index(), "[range] query malformed, no field to indicate field name");
}
String fieldName = parser.currentName();
token = parser.nextToken();
if (token != XContentParser.Token.START_OBJECT) {
throw new QueryParsingException(parseContext.index(), "[range] query malformed, after field missing start object");
}
Object from = null;
Object to = null;
boolean includeLower = true;
boolean includeUpper = true;
float boost = 1.0f;
String currentFieldName = null;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
} else {
if ("from".equals(currentFieldName)) {
''' '''
from = parser.objectBytes();
} else if ("to".equals(currentFieldName)) {
to = parser.objectBytes();
} else if ("include_lower".equals(currentFieldName) || "includeLower".equals(currentFieldName)) {
includeLower = parser.booleanValue();
} else if ("include_upper".equals(currentFieldName) || "includeUpper".equals(currentFieldName)) {
includeUpper = parser.booleanValue();
} else if ("boost".equals(currentFieldName)) {
boost = parser.floatValue();
} else if ("gt".equals(currentFieldName)) {
from = parser.objectBytes();
includeLower = false;
} else if ("gte".equals(currentFieldName) || "ge".equals(currentFieldName)) {
from = parser.objectBytes();
''' '''
includeLower = true;
} else if ("lt".equals(currentFieldName)) {
to = parser.objectBytes();
''' '''
includeUpper = false;
} else if ("lte".equals(currentFieldName) || "le".equals(currentFieldName)) {
''' '''
to = parser.objectBytes();
includeUpper = true;
} else {
throw new QueryParsingException(parseContext.index(), "[range] query does not support [" + currentFieldName + "]");
}
}
}
// move to the next end object, to close the field name
token = parser.nextToken();
if (token != XContentParser.Token.END_OBJECT) {
throw new QueryParsingException(parseContext.index(), "[range] query malformed, does not end with an object");
}
Query query = null;
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
if (smartNameFieldMappers != null) {
if (smartNameFieldMappers.hasMapper()) {
//LUCENE 4 UPGRADE Mapper#rangeQuery should use bytesref as well?
query = smartNameFieldMappers.mapper().rangeQuery(from, to, includeLower, includeUpper, parseContext);
}
}
if (query == null) {
''' Lucene TermRangeQuery '''
query = new TermRangeQuery(fieldName, BytesRefs.toBytesRef(from), BytesRefs.toBytesRef(to), includeLower, includeUpper);
}
query.setBoost(boost);
return wrapSmartNameQuery(query, smartNameFieldMappers, parseContext);
}
}
'''(2)Lucene code'''
''' TermRangeQuery TermRangeFilter '''
public class TermRangeFilter extends MultiTermQueryWrapperFilter<TermRangeQuery> {
...
/** * Constructs a filter for field <code>fieldName</code> matching * less than or equal to <code>upperTerm</code>. */
public static TermRangeFilter Less(String fieldName, BytesRef upperTerm) {
return new TermRangeFilter(fieldName, null, upperTerm, false, true);
}
/** * Constructs a filter for field <code>fieldName</code> matching * greater than or equal to <code>lowerTerm</code>. */
public static TermRangeFilter More(String fieldName, BytesRef lowerTerm) {
return new TermRangeFilter(fieldName, lowerTerm, null, true, false);
}
}
'''(3)Lucene '''
public void testExclusive() throws Exception {
''' (A,C), , B '''
Query query = TermRangeQuery.newStringRange("content", "A", "C", false, false);
initializeIndex(new String[] {"A", "B", "C", "D"});
IndexReader reader = DirectoryReader.open(dir);
IndexSearcher searcher = newSearcher(reader);
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
assertEquals("A,B,C,D, only B in range", 1, hits.length);
reader.close();
initializeIndex(new String[] {"A", "B", "D"});
reader = DirectoryReader.open(dir);
searcher = newSearcher(reader);
hits = searcher.search(query, 1000).scoreDocs;
assertEquals("A,B,D, only B in range", 1, hits.length);
reader.close();
addDoc("C");
reader = DirectoryReader.open(dir);
searcher = newSearcher(reader);
hits = searcher.search(query, 1000).scoreDocs;
assertEquals("C added, still only B in range", 1, hits.length);
reader.close();
}
public void testInclusive() throws Exception {
''' [A,C], ,A、B、C '''
Query query = TermRangeQuery.newStringRange("content", "A", "C", true, true);
initializeIndex(new String[]{"A", "B", "C", "D"});
IndexReader reader = DirectoryReader.open(dir);
IndexSearcher searcher = newSearcher(reader);
ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs;
assertEquals("A,B,C,D - A,B,C in range", 3, hits.length);
reader.close();
initializeIndex(new String[]{"A", "B", "D"});
reader = DirectoryReader.open(dir);
searcher = newSearcher(reader);
hits = searcher.search(query, 1000).scoreDocs;
assertEquals("A,B,D - A and B in range", 2, hits.length);
reader.close();
addDoc("C");
reader = DirectoryReader.open(dir);
searcher = newSearcher(reader);
hits = searcher.search(query, 1000).scoreDocs;
assertEquals("C added - A, B, C in range", 3, hits.length);
reader.close();
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
kafka connect e elasticsearch를 관찰할 수 있습니다.No menu lateral do dashboard tem a opção de connectors onde ele mostra todos os clusters do kafka connect conectados atu...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.