Skip to content

Commit 8cdcb34

Browse files
committed
Query Refactoring: Add RangeQueryBuilder and Parser refactoring and test.
Split the parse(QueryParseContext ctx) method into a parsing and a query building part, adding Streamable support for serialization and hashCode(), equals() for better testing. This PR also adds test setup for two mappes fields (integer, date) to the BaseQueryTestCase and introduces helper methods for optional conversion of String fields to BytesRef representation that is shared with the already refactored BaseTermQueryBuilder. Relates to elastic#10217 Closes elastic#11108
1 parent b014eb3 commit 8cdcb34

File tree

6 files changed

+485
-324
lines changed

6 files changed

+485
-324
lines changed

src/main/java/org/elasticsearch/index/query/BaseTermQueryBuilder.java

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,13 @@
2323
import org.elasticsearch.common.io.stream.StreamInput;
2424
import org.elasticsearch.common.io.stream.StreamOutput;
2525
import org.elasticsearch.common.io.stream.Streamable;
26-
import org.elasticsearch.common.lucene.BytesRefs;
2726
import org.elasticsearch.common.xcontent.XContentBuilder;
2827

2928
import java.io.IOException;
3029
import java.util.Objects;
3130

3231
public abstract class BaseTermQueryBuilder<QB extends BoostableQueryBuilder<QB>> extends QueryBuilder implements Streamable, BoostableQueryBuilder<QB> {
33-
32+
3433
/** Name of field to match against. */
3534
protected String fieldName;
3635

@@ -105,17 +104,16 @@ public BaseTermQueryBuilder(String fieldName, boolean value) {
105104

106105
/**
107106
* Constructs a new base term query.
107+
* In case value is assigned to a string, we internally convert it to a {@link BytesRef}
108+
* because in {@link TermQueryParser} and {@link SpanTermQueryParser} string values are parsed to {@link BytesRef}
109+
* and we want internal representation of query to be equal regardless of whether it was created from XContent or via Java API.
108110
*
109111
* @param fieldName The name of the field
110112
* @param value The value of the term
111113
*/
112114
public BaseTermQueryBuilder(String fieldName, Object value) {
113115
this.fieldName = fieldName;
114-
if (value instanceof String) {
115-
this.value = BytesRefs.toBytesRef(value);
116-
} else {
117-
this.value = value;
118-
}
116+
this.value = convertToBytesRefIfString(value);
119117
}
120118

121119
BaseTermQueryBuilder() {
@@ -127,11 +125,14 @@ public String fieldName() {
127125
return this.fieldName;
128126
}
129127

130-
/** Returns the value used in this query. */
128+
/**
129+
* Returns the value used in this query.
130+
* If necessary, converts internal {@link BytesRef} representation back to string.
131+
*/
131132
public Object value() {
132-
return this.value;
133+
return convertToStringIfBytesRef(this.value);
133134
}
134-
135+
135136
/** Returns the query name for the query. */
136137
public String queryName() {
137138
return this.queryName;
@@ -144,7 +145,7 @@ public QB queryName(String queryName) {
144145
this.queryName = queryName;
145146
return (QB) this;
146147
}
147-
148+
148149
/** Returns the boost for this query. */
149150
public float boost() {
150151
return this.boost;
@@ -163,16 +164,11 @@ public QB boost(float boost) {
163164
@Override
164165
protected void doXContent(XContentBuilder builder, Params params) throws IOException {
165166
builder.startObject(parserName());
166-
Object valueToWrite = value;
167-
if (value instanceof BytesRef) {
168-
valueToWrite = ((BytesRef) value).utf8ToString();
169-
}
170-
171167
if (boost == 1.0f && queryName == null) {
172-
builder.field(fieldName, valueToWrite);
168+
builder.field(fieldName, convertToStringIfBytesRef(this.value));
173169
} else {
174170
builder.startObject(fieldName);
175-
builder.field("value", valueToWrite);
171+
builder.field("value", convertToStringIfBytesRef(this.value));
176172
if (boost != 1.0f) {
177173
builder.field("boost", boost);
178174
}
@@ -183,7 +179,7 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
183179
}
184180
builder.endObject();
185181
}
186-
182+
187183
/** Returns a {@link QueryValidationException} if fieldName is null or empty, or if value is null. */
188184
@Override
189185
public QueryValidationException validate() {
@@ -194,7 +190,7 @@ public QueryValidationException validate() {
194190
if (value == null) {
195191
validationException = QueryValidationException.addValidationError("value cannot be null.", validationException);
196192
}
197-
return validationException;
193+
return validationException;
198194
}
199195

200196
@Override

src/main/java/org/elasticsearch/index/query/QueryBuilder.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
import org.apache.lucene.search.Query;
2323
import org.elasticsearch.action.support.ToXContentToBytes;
24+
import org.apache.lucene.util.BytesRef;
25+
import org.elasticsearch.common.lucene.BytesRefs;
2426
import org.elasticsearch.common.xcontent.XContentBuilder;
2527
import org.elasticsearch.common.xcontent.XContentType;
2628

@@ -75,4 +77,30 @@ public QueryValidationException validate() {
7577
}
7678

7779
protected abstract void doXContent(XContentBuilder builder, Params params) throws IOException;
80+
81+
/**
82+
* This helper method checks if the object passed in is a string, if so it
83+
* converts it to a {@link BytesRef}.
84+
* @param obj the input object
85+
* @return the same input object or a {@link BytesRef} representation if input was of type string
86+
*/
87+
protected static Object convertToBytesRefIfString(Object obj) {
88+
if (obj instanceof String) {
89+
return BytesRefs.toBytesRef(obj);
90+
}
91+
return obj;
92+
}
93+
94+
/**
95+
* This helper method checks if the object passed in is a {@link BytesRef}, if so it
96+
* converts it to a utf8 string.
97+
* @param obj the input object
98+
* @return the same input object or a utf8 string if input was of type {@link BytesRef}
99+
*/
100+
protected static Object convertToStringIfBytesRef(Object obj) {
101+
if (obj instanceof BytesRef) {
102+
return ((BytesRef) obj).utf8ToString();
103+
}
104+
return obj;
105+
}
78106
}

0 commit comments

Comments
 (0)