public static ValidationException validateKnnField()

in src/main/java/org/opensearch/knn/index/IndexUtil.java [58:158]


    public static ValidationException validateKnnField(IndexMetadata indexMetadata, String field, int expectedDimension,
                                                       ModelDao modelDao) {
        // Index metadata should not be null
        if (indexMetadata == null) {
            throw new IllegalArgumentException("IndexMetadata should not be null");
        }

        ValidationException exception = new ValidationException();

        // Check the mapping
        MappingMetadata mappingMetadata = indexMetadata.mapping();
        if (mappingMetadata == null) {
            exception.addValidationError("Invalid index. Index does not contain a mapping");
            return exception;
        }

        // The mapping output *should* look like this:
        //  "{properties={field={type=knn_vector, dimension=8}}}"
        Map<String, Object> properties = (Map<String, Object>)mappingMetadata.getSourceAsMap().get("properties");

        if (properties == null) {
            exception.addValidationError("Properties in map does not exists. This is unexpected");
            return exception;
        }

        Object fieldMapping = properties.get(field);

        // Check field existence
        if (fieldMapping == null) {
            exception.addValidationError(String.format("Field \"%s\" does not exist.", field));
            return exception;
        }

        // Check if field is a map. If not, that is a problem
        if (!(fieldMapping instanceof Map)) {
            exception.addValidationError(String.format("Field info for \"%s\" is not a map.", field));
            return exception;
        }

        Map<String, Object> fieldMap = (Map<String, Object>) fieldMapping;

        // Check fields type is knn_vector
        Object type = fieldMap.get("type");

        if (!(type instanceof String) || !KNNVectorFieldMapper.CONTENT_TYPE.equals(type)) {
            exception.addValidationError(String.format("Field \"%s\" is not of type %s.", field,
                    KNNVectorFieldMapper.CONTENT_TYPE));
            return exception;
        }

        // Return if dimension does not need to be checked
        if (expectedDimension < 0) {
            return null;
        }

        // Check that the dimension of the method passed in matches that of the model
        Object dimension = fieldMap.get(KNNConstants.DIMENSION);

        // If dimension is null, the training index/field could use a model. In this case, we need to get the model id
        // for the index and then fetch its dimension from the models metadata
        if (dimension == null) {

            String modelId = (String) fieldMap.get(KNNConstants.MODEL_ID);

            if (modelId == null) {
                exception.addValidationError(String.format("Field \"%s\" does not have a dimension set.", field));
                return exception;
            }

            if (modelDao == null) {
                throw new IllegalArgumentException(String.format("Field \"%s\" uses model. modelDao cannot be null.",
                        field));
            }

            ModelMetadata modelMetadata = modelDao.getMetadata(modelId);
            if (modelMetadata == null) {
                exception.addValidationError(String.format("Model \"%s\" for field \"%s\" does not exist.", modelId,
                        field));
                return exception;
            }

            dimension = modelMetadata.getDimension();
            if ((Integer) dimension != expectedDimension) {
                exception.addValidationError(String.format("Field \"%s\" has dimension %d, which is different from " +
                                "dimension specified in the training request: %d", field, dimension,
                        expectedDimension));
                return exception;
            }

            return null;
        }

        // If the dimension was found in training fields mapping, check that it equals the models proposed dimension.
        if ((Integer) dimension != expectedDimension) {
            exception.addValidationError(String.format("Field \"%s\" has dimension %d, which is different from " +
                    "dimension specified in the training request: %d", field, dimension, expectedDimension));
            return exception;
        }

        return null;
    }