Skip to content

Commit 6ab6c4a

Browse files
serbaAlexey Serba
andauthored
SOLR-10255 Add support for docValues to solr.BinaryField (#2536)
Co-authored-by: Alexey Serba <[email protected]>
1 parent 3884870 commit 6ab6c4a

File tree

6 files changed

+93
-47
lines changed

6 files changed

+93
-47
lines changed

solr/CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ New Features
122122
overridden with a property ('solr.query.minPrefixLength'). Users may also override their collection-wide setting for individual queries by providing a
123123
`minPrefixQueryTermLength` local-param. (Jason Gerlowski, David Smiley)
124124

125+
* SOLR-10255: Add support for docValues to solr.BinaryField. (Alexey Serba via Mikhail Khludnev, David Smiley)
126+
125127
Improvements
126128
---------------------
127129
* SOLR-17137: Enable Prometheus exporter to communicate with SSL protected Solr. (Eivind Bergstøl via Eric Pugh)

solr/core/src/java/org/apache/solr/schema/BinaryField.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
import java.lang.invoke.MethodHandles;
2121
import java.nio.ByteBuffer;
2222
import java.nio.charset.StandardCharsets;
23+
import java.util.ArrayList;
2324
import java.util.Base64;
25+
import java.util.Collections;
26+
import java.util.List;
27+
import org.apache.lucene.document.BinaryDocValuesField;
2428
import org.apache.lucene.index.IndexableField;
2529
import org.apache.lucene.search.SortField;
2630
import org.apache.lucene.util.BytesRef;
@@ -42,6 +46,11 @@ public void checkSchemaField(SchemaField field) {
4246
SolrException.ErrorCode.SERVER_ERROR,
4347
"Field type " + this + " is 'large'; not supported (yet)");
4448
}
49+
if (field.hasDocValues() && field.multiValued()) {
50+
throw new SolrException(
51+
SolrException.ErrorCode.SERVER_ERROR,
52+
"Field type " + this + " does not support multiple doc values");
53+
}
4554
}
4655

4756
private String toBase64String(ByteBuffer buf) {
@@ -94,6 +103,10 @@ public IndexableField createField(SchemaField field, Object val) {
94103
log.trace("Ignoring unstored binary field: {}", field);
95104
return null;
96105
}
106+
return new org.apache.lucene.document.StoredField(field.getName(), getBytesRef(val));
107+
}
108+
109+
private static BytesRef getBytesRef(Object val) {
97110
byte[] buf = null;
98111
int offset = 0, len = 0;
99112
if (val instanceof byte[]) {
@@ -112,7 +125,31 @@ public IndexableField createField(SchemaField field, Object val) {
112125
len = buf.length;
113126
}
114127

115-
return new org.apache.lucene.document.StoredField(field.getName(), buf, offset, len);
128+
return new BytesRef(buf, offset, len);
129+
}
130+
131+
@Override
132+
public List<IndexableField> createFields(SchemaField field, Object val) {
133+
IndexableField fval = createField(field, val);
134+
135+
if (field.hasDocValues() && !field.multiValued()) {
136+
IndexableField docval = new BinaryDocValuesField(field.getName(), getBytesRef(val));
137+
138+
// Only create list if we have 2 values...
139+
if (fval != null) {
140+
List<IndexableField> fields = new ArrayList<>(2);
141+
fields.add(fval);
142+
fields.add(docval);
143+
return fields;
144+
}
145+
146+
fval = docval;
147+
}
148+
return Collections.singletonList(fval);
149+
}
150+
151+
@Override
152+
protected void checkSupportsDocValues() { // we support DocValues
116153
}
117154

118155
@Override

solr/core/src/java/org/apache/solr/search/SolrDocumentFetcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ private Object decodeDVField(
639639
case BINARY:
640640
BinaryDocValues bdv = e.getBinaryDocValues(localId, leafReader, readerOrd);
641641
if (bdv != null) {
642-
return BytesRef.deepCopyOf(bdv.binaryValue());
642+
return BytesRef.deepCopyOf(bdv.binaryValue()).bytes;
643643
}
644644
return null;
645645
case SORTED:

solr/core/src/test-files/solr/collection1/conf/bad-schema-unsupported-docValues.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
-->
1818

1919
<schema name="bad-schema-docValues-unsupported" version="1.6">
20-
<fieldType name="binary" class="solr.BinaryField"/>
20+
<fieldType name="random" class="solr.RandomSortField" />
2121

2222

23-
<!-- change the type if BinaryField gets doc values -->
24-
<field name="id" type="binary" docValues="true"/>
23+
<!-- change the type if RandomSortField gets doc values -->
24+
<field name="id" type="random" docValues="true"/>
2525

2626
</schema>

solr/core/src/test-files/solr/collection1/conf/schema-binaryfield.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
3535
<field name="data" type="binary" stored="true"/>
36+
<field name="data_dv" type="binary" stored="false" docValues="true" />
3637

3738

3839
<uniqueKey>id</uniqueKey>

solr/core/src/test/org/apache/solr/schema/TestBinaryField.java

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -82,73 +82,78 @@ public void testSimple() throws Exception {
8282
doc = new SolrInputDocument();
8383
doc.addField("id", 1);
8484
doc.addField("data", ByteBuffer.wrap(buf, 2, 5));
85+
doc.addField("data_dv", ByteBuffer.wrap(buf, 2, 5));
8586
client.add(doc);
8687

8788
doc = new SolrInputDocument();
8889
doc.addField("id", 2);
8990
doc.addField("data", ByteBuffer.wrap(buf, 4, 3));
91+
doc.addField("data_dv", ByteBuffer.wrap(buf, 4, 3));
9092
client.add(doc);
9193

9294
doc = new SolrInputDocument();
9395
doc.addField("id", 3);
9496
doc.addField("data", buf);
97+
doc.addField("data_dv", buf);
9598
client.add(doc);
9699

97100
client.commit();
98101

99-
QueryResponse resp = client.query(new SolrQuery("*:*"));
102+
QueryResponse resp = client.query(new SolrQuery("*:*").setFields("id", "data", "data_dv"));
100103
SolrDocumentList res = resp.getResults();
101104
List<Bean> beans = resp.getBeans(Bean.class);
102105
assertEquals(3, res.size());
103106
assertEquals(3, beans.size());
104107
for (SolrDocument d : res) {
105-
106108
Integer id = Integer.parseInt(d.getFieldValue("id").toString());
107-
byte[] data = (byte[]) d.getFieldValue("data");
108-
if (id == 1) {
109-
assertEquals(5, data.length);
110-
for (int i = 0; i < data.length; i++) {
111-
byte b = data[i];
112-
assertEquals((byte) (i + 2), b);
113-
}
114-
115-
} else if (id == 2) {
116-
assertEquals(3, data.length);
117-
for (int i = 0; i < data.length; i++) {
118-
byte b = data[i];
119-
assertEquals((byte) (i + 4), b);
120-
}
121-
122-
} else if (id == 3) {
123-
assertEquals(10, data.length);
124-
for (int i = 0; i < data.length; i++) {
125-
byte b = data[i];
126-
assertEquals((byte) i, b);
109+
for (String field : new String[] {"data", "data_dv"}) {
110+
byte[] data = (byte[]) d.getFieldValue(field);
111+
if (id == 1) {
112+
assertEquals(5, data.length);
113+
for (int i = 0; i < data.length; i++) {
114+
byte b = data[i];
115+
assertEquals((byte) (i + 2), b);
116+
}
117+
118+
} else if (id == 2) {
119+
assertEquals(3, data.length);
120+
for (int i = 0; i < data.length; i++) {
121+
byte b = data[i];
122+
assertEquals((byte) (i + 4), b);
123+
}
124+
125+
} else if (id == 3) {
126+
assertEquals(10, data.length);
127+
for (int i = 0; i < data.length; i++) {
128+
byte b = data[i];
129+
assertEquals((byte) i, b);
130+
}
127131
}
128132
}
129133
}
130134
for (Bean d : beans) {
131135
Integer id = Integer.parseInt(d.id);
132-
byte[] data = d.data;
133-
if (id == 1) {
134-
assertEquals(5, data.length);
135-
for (int i = 0; i < data.length; i++) {
136-
byte b = data[i];
137-
assertEquals((byte) (i + 2), b);
138-
}
139-
140-
} else if (id == 2) {
141-
assertEquals(3, data.length);
142-
for (int i = 0; i < data.length; i++) {
143-
byte b = data[i];
144-
assertEquals((byte) (i + 4), b);
145-
}
146-
147-
} else if (id == 3) {
148-
assertEquals(10, data.length);
149-
for (int i = 0; i < data.length; i++) {
150-
byte b = data[i];
151-
assertEquals((byte) i, b);
136+
for (byte[] data : new byte[][] {d.data, d.data_dv}) {
137+
if (id == 1) {
138+
assertEquals(5, data.length);
139+
for (int i = 0; i < data.length; i++) {
140+
byte b = data[i];
141+
assertEquals((byte) (i + 2), b);
142+
}
143+
144+
} else if (id == 2) {
145+
assertEquals(3, data.length);
146+
for (int i = 0; i < data.length; i++) {
147+
byte b = data[i];
148+
assertEquals((byte) (i + 4), b);
149+
}
150+
151+
} else if (id == 3) {
152+
assertEquals(10, data.length);
153+
for (int i = 0; i < data.length; i++) {
154+
byte b = data[i];
155+
assertEquals((byte) i, b);
156+
}
152157
}
153158
}
154159
}
@@ -158,5 +163,6 @@ public void testSimple() throws Exception {
158163
public static class Bean {
159164
@Field String id;
160165
@Field byte[] data;
166+
@Field byte[] data_dv;
161167
}
162168
}

0 commit comments

Comments
 (0)