es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo se puede admitir tanto expresiones regulares como un arreglo de valores exactos para incluir y excluir en Elasticsearch Java?

Estoy desarrollando una API de búsqueda que admite Aggregation utilizando Elasticsearch y GraphQL-Java.

Elasticsearch: ES admite una función llamada “include” y “exclude”, que como su nombre indica, incluirá o excluirá solo los campos de Aggregation solicitados por el usuario en la entrada.

La entrada de “include” y “exclude” se puede proporcionar de dos formas:
1. Como una expresión regular.

Por ejemplo: “include”: “P.*”

  1. Como un array de valores exactos.

Por ejemplo: “include”: [“Pune”,”Mumbai”]

Por lo tanto, para admitir ambas entradas, he mantenido un tipo como:

input: [String]

Problema: Quiero admitir tanto RegEx (String) como un array de valores exactos (String), pero con el tipo anterior, es decir, [String], incluso si paso una sola cadena como entrada en “include”, seguirá considerándose como un array de cadenas con un solo valor:

include: “P.” —> include: [“P.”]

Entonces, no puedo hacer una verificación de instancia en Java, ya que siempre será un array.

Hasta donde yo sé, GraphQL no admite una unión de tipos de entrada, por lo que no puedo cambiar el tipo de entrada para “include” como:

include: String | [String]

¿Alguien puede dirigirme a una solución?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una solución a este problema podría ser usar un tipo escalar personalizado para el campo de entrada, lo cual permitiría una mayor flexibilidad en la definición de las entradas. Este tipo escalar personalizado podría llamarse “AggregationInput” y se definiría en el esquema de GraphQL de la siguiente manera:

    scalar AggregationInput
    

    A continuación, definiríamos una implementación personalizada de este tipo escalar en el código, la cual analizaría la entrada y determinaría si se trata de un patrón regex o de un arreglo de valores exactos. Esta implementación debería implementar la interfaz Coercing, que define cómo analizar y serializar la entrada:

    public class AggregationInputCoercing implements Coercing<aggregationinput, object=""> {
    
        @Override
        public Object serialize(Object input) {
            // TODO: Convertir AggregationInput a un formato compatible con Elasticsearch
        }
    
        @Override
        public AggregationInput parseValue(Object input) {
            if (input instanceof String) {
                // Verificar si la entrada es un patrón regex
                String regex = (String) input;
                return new AggregationInput(Collections.singletonList(regex));
            } else if (input instanceof List) {
                // Verificar si la entrada es una lista de valores exactos
                List<string> values = ((List<object>) input)
                        .stream()
                        .map(Object::toString)
                        .collect(Collectors.toList());
                return new AggregationInput(values);
            } else {
                throw new CoercingParseValueException("Tipo de entrada no válido para AggregationInput");
            }
        }
    
        @Override
        public AggregationInput parseLiteral(Object input) {
            // TODO: Implementar el análisis de valores literales (por ejemplo, desde una consulta de GraphQL)
            throw new CoercingParseLiteralException("El análisis de literales no está soportado para AggregationInput");
        }
    }
    

    Finalmente, definiríamos el campo de entrada para la API de búsqueda de la siguiente manera:

    type Query {
      search(
        query: String
        include: AggregationInput
        exclude: AggregationInput
      ): SearchResult
    }
    

    Con este enfoque, el campo de entrada para los valores de agregación puede ser tanto una cadena única como un arreglo de cadenas, y el tipo escalar personalizado se encargará del análisis y serialización en un formato compatible con Elasticsearch. Además, dado que el tipo escalar personalizado se define por separado del campo de entrada, se puede reutilizar para otros campos de entrada donde se requiera una flexibilidad similar.</aggregationinput,>

Comments are closed.