Skip to content

Commit ce5230e

Browse files
authored
Cardinality Aggregator Throws UnsupportedOperationException When Field Type is Vector (#135994) (#136026)
1 parent 8778a2f commit ce5230e

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

docs/changelog/135994.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 135994
2+
summary: Cardinality Aggregator Throws `UnsupportedOperationException` When Field
3+
Type is Vector
4+
area: Vector Search
5+
type: bug
6+
issues: []

server/src/main/java/org/elasticsearch/index/mapper/vectors/VectorDVLeafFieldData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public long ramBytesUsed() {
6060

6161
@Override
6262
public SortedBinaryDocValues getBytesValues() {
63-
throw new UnsupportedOperationException("String representation of doc values for vector fields is not supported");
63+
throw new IllegalArgumentException("String representation of doc values for vector fields is not supported");
6464
}
6565

6666
@Override

server/src/main/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregator.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import org.elasticsearch.index.fielddata.NumericDoubleValues;
3333
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
3434
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
35+
import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper;
36+
import org.elasticsearch.index.mapper.vectors.SparseVectorFieldMapper;
3537
import org.elasticsearch.search.aggregations.AggregationExecutionContext;
3638
import org.elasticsearch.search.aggregations.Aggregator;
3739
import org.elasticsearch.search.aggregations.InternalAggregation;
@@ -73,6 +75,11 @@ public CardinalityAggregator(
7375
) throws IOException {
7476
super(name, context, parent, metadata);
7577
assert valuesSourceConfig.hasValues();
78+
if (valuesSourceConfig.fieldContext() != null
79+
&& (valuesSourceConfig.fieldContext().fieldType() instanceof DenseVectorFieldMapper.DenseVectorFieldType
80+
|| valuesSourceConfig.fieldContext().fieldType() instanceof SparseVectorFieldMapper.SparseVectorFieldType)) {
81+
throw new IllegalArgumentException("Cardinality aggregation [" + name + "] does not support vector fields");
82+
}
7683
this.valuesSource = valuesSourceConfig.getValuesSource();
7784
this.precision = precision;
7885
this.counts = new HyperLogLogPlusPlus(precision, context.bigArrays(), 1);

server/src/test/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregatorTests.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,16 @@
3131
import org.elasticsearch.common.settings.Settings;
3232
import org.elasticsearch.common.util.BigArrays;
3333
import org.elasticsearch.core.CheckedConsumer;
34+
import org.elasticsearch.index.IndexVersion;
3435
import org.elasticsearch.index.fielddata.ScriptDocValues;
3536
import org.elasticsearch.index.mapper.IpFieldMapper;
3637
import org.elasticsearch.index.mapper.KeywordFieldMapper;
3738
import org.elasticsearch.index.mapper.MappedFieldType;
3839
import org.elasticsearch.index.mapper.NumberFieldMapper;
3940
import org.elasticsearch.index.mapper.RangeFieldMapper;
4041
import org.elasticsearch.index.mapper.RangeType;
42+
import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper;
43+
import org.elasticsearch.index.mapper.vectors.SparseVectorFieldMapper;
4144
import org.elasticsearch.script.MockScriptEngine;
4245
import org.elasticsearch.script.Script;
4346
import org.elasticsearch.script.ScriptEngine;
@@ -217,6 +220,51 @@ public void testQueryFiltersAll() throws IOException {
217220
});
218221
}
219222

223+
public void testVectorValueThrows() {
224+
final CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("card_agg_name").field("vector_value");
225+
final MappedFieldType mappedFieldTypes;
226+
boolean isDense = randomBoolean();
227+
if (isDense) {
228+
mappedFieldTypes = new DenseVectorFieldMapper.DenseVectorFieldType(
229+
"vector_value",
230+
IndexVersion.current(),
231+
DenseVectorFieldMapper.ElementType.FLOAT,
232+
64,
233+
true,
234+
DenseVectorFieldMapper.VectorSimilarity.COSINE,
235+
DenseVectorFieldMapper.VectorIndexType.FLAT.parseIndexOptions("vector_value", new HashMap<>(), IndexVersion.current()),
236+
new HashMap<>(),
237+
false
238+
);
239+
} else {
240+
mappedFieldTypes = new SparseVectorFieldMapper.SparseVectorFieldType(
241+
IndexVersion.current(),
242+
"vector_value",
243+
false,
244+
new HashMap<>()
245+
);
246+
}
247+
248+
IllegalArgumentException exception = assertThrows(
249+
IllegalArgumentException.class,
250+
() -> testAggregation(aggregationBuilder, new MatchAllDocsQuery(), iw -> {
251+
iw.addDocument(singleton(new SortedDocValuesField("vector_value", new BytesRef("one"))));
252+
iw.addDocument(singleton(new SortedDocValuesField("unrelatedField", new BytesRef("two"))));
253+
iw.addDocument(singleton(new SortedDocValuesField("str_value", new BytesRef("three"))));
254+
iw.addDocument(singleton(new SortedDocValuesField("str_value", new BytesRef("one"))));
255+
}, card -> {
256+
assertEquals(2, card.getValue(), 0);
257+
assertTrue(AggregationInspectionHelper.hasValue(card));
258+
}, mappedFieldTypes)
259+
);
260+
261+
if (isDense) {
262+
assertEquals("Cardinality aggregation [card_agg_name] does not support vector fields", exception.getMessage());
263+
} else {
264+
assertEquals("[sparse_vector] fields do not support sorting, scripting or aggregating", exception.getMessage());
265+
}
266+
}
267+
220268
public void testSingleValuedString() throws IOException {
221269
final CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("name").field("str_value");
222270
final MappedFieldType mappedFieldTypes = new KeywordFieldMapper.KeywordFieldType("str_value");

0 commit comments

Comments
 (0)