Skip to content

Commit 03dd73d

Browse files
authored
Fix for wildcard fields that returned ByteRefs not Strings to scripts. (elastic#58060) (elastic#58109)
This need some reorg of BinaryDV field data classes to allow specialisation of scripted doc values. Moved common logic to a new abstract base class and added a new subclass to return string-based representations to scripts. Closes elastic#58044
1 parent 0bc7c4f commit 03dd73d

File tree

6 files changed

+245
-91
lines changed

6 files changed

+245
-91
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.fielddata.plain;
21+
22+
import org.apache.lucene.index.BinaryDocValues;
23+
import org.apache.lucene.store.ByteArrayDataInput;
24+
import org.apache.lucene.util.Accountable;
25+
import org.apache.lucene.util.BytesRef;
26+
import org.elasticsearch.index.fielddata.LeafFieldData;
27+
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
28+
29+
import java.io.IOException;
30+
import java.util.Collection;
31+
import java.util.Collections;
32+
33+
abstract class AbstractBinaryDVLeafFieldData implements LeafFieldData {
34+
private final BinaryDocValues values;
35+
36+
AbstractBinaryDVLeafFieldData(BinaryDocValues values) {
37+
super();
38+
this.values = values;
39+
}
40+
41+
@Override
42+
public long ramBytesUsed() {
43+
return 0; // not exposed by Lucene
44+
}
45+
46+
@Override
47+
public Collection<Accountable> getChildResources() {
48+
return Collections.emptyList();
49+
}
50+
51+
@Override
52+
public SortedBinaryDocValues getBytesValues() {
53+
return new SortedBinaryDocValues() {
54+
55+
int count;
56+
final ByteArrayDataInput in = new ByteArrayDataInput();
57+
final BytesRef scratch = new BytesRef();
58+
59+
@Override
60+
public boolean advanceExact(int doc) throws IOException {
61+
if (values.advanceExact(doc)) {
62+
final BytesRef bytes = values.binaryValue();
63+
assert bytes.length > 0;
64+
in.reset(bytes.bytes, bytes.offset, bytes.length);
65+
count = in.readVInt();
66+
scratch.bytes = bytes.bytes;
67+
return true;
68+
} else {
69+
return false;
70+
}
71+
}
72+
73+
@Override
74+
public int docValueCount() {
75+
return count;
76+
}
77+
78+
@Override
79+
public BytesRef nextValue() throws IOException {
80+
scratch.length = in.readVInt();
81+
scratch.offset = in.getPosition();
82+
in.setPosition(scratch.offset + scratch.length);
83+
return scratch;
84+
}
85+
86+
};
87+
}
88+
89+
90+
@Override
91+
public void close() {
92+
// no-op
93+
}
94+
}

server/src/main/java/org/elasticsearch/index/fielddata/plain/BytesBinaryDVLeafFieldData.java

Lines changed: 3 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -20,83 +20,18 @@
2020
package org.elasticsearch.index.fielddata.plain;
2121

2222
import org.apache.lucene.index.BinaryDocValues;
23-
import org.apache.lucene.store.ByteArrayDataInput;
24-
import org.apache.lucene.util.Accountable;
2523
import org.apache.lucene.util.BytesRef;
26-
import org.elasticsearch.index.fielddata.LeafFieldData;
2724
import org.elasticsearch.index.fielddata.ScriptDocValues;
28-
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
2925

30-
import java.io.IOException;
31-
import java.util.Collection;
32-
import java.util.Collections;
33-
34-
final class BytesBinaryDVLeafFieldData implements LeafFieldData {
35-
36-
private final BinaryDocValues values;
3726

27+
final class BytesBinaryDVLeafFieldData extends AbstractBinaryDVLeafFieldData {
3828
BytesBinaryDVLeafFieldData(BinaryDocValues values) {
39-
super();
40-
this.values = values;
41-
}
42-
43-
@Override
44-
public long ramBytesUsed() {
45-
return 0; // not exposed by Lucene
46-
}
47-
48-
@Override
49-
public Collection<Accountable> getChildResources() {
50-
return Collections.emptyList();
51-
}
52-
53-
@Override
54-
public SortedBinaryDocValues getBytesValues() {
55-
return new SortedBinaryDocValues() {
56-
57-
int count;
58-
final ByteArrayDataInput in = new ByteArrayDataInput();
59-
final BytesRef scratch = new BytesRef();
60-
61-
@Override
62-
public boolean advanceExact(int doc) throws IOException {
63-
if (values.advanceExact(doc)) {
64-
final BytesRef bytes = values.binaryValue();
65-
assert bytes.length > 0;
66-
in.reset(bytes.bytes, bytes.offset, bytes.length);
67-
count = in.readVInt();
68-
scratch.bytes = bytes.bytes;
69-
return true;
70-
} else {
71-
return false;
72-
}
73-
}
74-
75-
@Override
76-
public int docValueCount() {
77-
return count;
78-
}
79-
80-
@Override
81-
public BytesRef nextValue() throws IOException {
82-
scratch.length = in.readVInt();
83-
scratch.offset = in.getPosition();
84-
in.setPosition(scratch.offset + scratch.length);
85-
return scratch;
86-
}
87-
88-
};
29+
super(values);
8930
}
9031

9132
@Override
9233
public ScriptDocValues<BytesRef> getScriptValues() {
9334
return new ScriptDocValues.BytesRefs(getBytesValues());
9435
}
95-
96-
@Override
97-
public void close() {
98-
// no-op
99-
}
100-
101-
10236
}
37+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.fielddata.plain;
21+
22+
import org.apache.lucene.index.BinaryDocValues;
23+
import org.elasticsearch.index.fielddata.ScriptDocValues;
24+
25+
final class StringBinaryDVLeafFieldData extends AbstractBinaryDVLeafFieldData{
26+
StringBinaryDVLeafFieldData(BinaryDocValues values) {
27+
super(values);
28+
}
29+
30+
@Override
31+
public ScriptDocValues<String> getScriptValues() {
32+
return new ScriptDocValues.Strings(getBytesValues());
33+
}
34+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.index.fielddata.plain;
21+
22+
import org.apache.lucene.index.DocValues;
23+
import org.apache.lucene.index.LeafReaderContext;
24+
import org.apache.lucene.search.SortField;
25+
import org.elasticsearch.common.util.BigArrays;
26+
import org.elasticsearch.index.Index;
27+
import org.elasticsearch.index.fielddata.IndexFieldData;
28+
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
29+
import org.elasticsearch.index.fielddata.fieldcomparator.BytesRefFieldComparatorSource;
30+
import org.elasticsearch.search.DocValueFormat;
31+
import org.elasticsearch.search.MultiValueMode;
32+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
33+
import org.elasticsearch.search.sort.BucketedSort;
34+
import org.elasticsearch.search.sort.SortOrder;
35+
36+
import java.io.IOException;
37+
38+
public class StringBinaryIndexFieldData implements IndexFieldData<StringBinaryDVLeafFieldData> {
39+
40+
protected final Index index;
41+
protected final String fieldName;
42+
protected final ValuesSourceType valuesSourceType;
43+
44+
public StringBinaryIndexFieldData(Index index, String fieldName, ValuesSourceType valuesSourceType) {
45+
this.index = index;
46+
this.fieldName = fieldName;
47+
this.valuesSourceType = valuesSourceType;
48+
}
49+
50+
@Override
51+
public final String getFieldName() {
52+
return fieldName;
53+
}
54+
55+
@Override
56+
public ValuesSourceType getValuesSourceType() {
57+
return valuesSourceType;
58+
}
59+
60+
@Override
61+
public final void clear() {
62+
// can't do
63+
}
64+
65+
@Override
66+
public final Index index() {
67+
return index;
68+
}
69+
70+
@Override
71+
public SortField sortField(Object missingValue, MultiValueMode sortMode, Nested nested, boolean reverse) {
72+
XFieldComparatorSource source = new BytesRefFieldComparatorSource(this, missingValue,
73+
sortMode, nested);
74+
return new SortField(getFieldName(), source, reverse);
75+
}
76+
77+
@Override
78+
public StringBinaryDVLeafFieldData load(LeafReaderContext context) {
79+
try {
80+
return new StringBinaryDVLeafFieldData(DocValues.getBinary(context.reader(), fieldName));
81+
} catch (IOException e) {
82+
throw new IllegalStateException("Cannot load doc values", e);
83+
}
84+
}
85+
@Override
86+
public BucketedSort newBucketedSort(BigArrays bigArrays, Object missingValue, MultiValueMode sortMode, Nested nested,
87+
SortOrder sortOrder, DocValueFormat format, int bucketSize, BucketedSort.ExtraData extra) {
88+
throw new IllegalArgumentException("can't sort on binary field");
89+
}
90+
91+
@Override
92+
public StringBinaryDVLeafFieldData loadDirect(LeafReaderContext context) throws Exception {
93+
return load(context);
94+
}
95+
}

x-pack/plugin/src/test/resources/rest-api-spec/test/wildcard/10_wildcard_basic.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,23 @@ setup:
229229
- length: { aggregations.top_vals.buckets: 2 }
230230

231231
---
232+
"Scripted Aggs work":
233+
- do:
234+
search:
235+
body:
236+
track_total_hits: true
237+
query:
238+
wildcard:
239+
my_wildcard: {value: "*goodbye*" }
240+
aggs:
241+
top_vals:
242+
terms: {script: "doc['my_wildcard']" }
243+
244+
245+
- match: {hits.total.value: 1}
246+
- length: { aggregations.top_vals.buckets: 1 }
247+
- match: { aggregations.top_vals.buckets.0.key: "goodbye world" }
248+
---
232249
"Sort works":
233250
- do:
234251
search:

0 commit comments

Comments
 (0)