Skip to content

Commit b624964

Browse files
committed
Cardinality Aggregator Throws UnsupportedOperationException When Field Type is Vector (elastic#135994)
1 parent 0778efe commit b624964

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
@@ -32,13 +32,16 @@
3232
import org.elasticsearch.common.settings.Settings;
3333
import org.elasticsearch.common.util.BigArrays;
3434
import org.elasticsearch.core.CheckedConsumer;
35+
import org.elasticsearch.index.IndexVersion;
3536
import org.elasticsearch.index.fielddata.ScriptDocValues;
3637
import org.elasticsearch.index.mapper.IpFieldMapper;
3738
import org.elasticsearch.index.mapper.KeywordFieldMapper;
3839
import org.elasticsearch.index.mapper.MappedFieldType;
3940
import org.elasticsearch.index.mapper.NumberFieldMapper;
4041
import org.elasticsearch.index.mapper.RangeFieldMapper;
4142
import org.elasticsearch.index.mapper.RangeType;
43+
import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper;
44+
import org.elasticsearch.index.mapper.vectors.SparseVectorFieldMapper;
4245
import org.elasticsearch.script.MockScriptEngine;
4346
import org.elasticsearch.script.Script;
4447
import org.elasticsearch.script.ScriptEngine;
@@ -224,6 +227,51 @@ public void testQueryFiltersAll() throws IOException {
224227
});
225228
}
226229

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

0 commit comments

Comments
 (0)