Query ElasticSearch: use SQL en lugar de DSL

La versión ES7.x de x-pack viene con ElasticSearch SQL, y podemos usar consultas SQL directamente a través de SQL REST API, SQL CLI, etc.

API REST de SQL

Ingrese en Kibana Console:

POST /_sql?format=txt
{
  "query": "SELECT * FROM library ORDER BY page_count DESC LIMIT 5"
}

Reemplace el SQL anterior con su propia declaración SQL. El formato de devolución es el siguiente:

    author      |        name        |  page_count   | release_date
-----------------+--------------------+---------------+------------------------
Peter F. Hamilton|Pandora's Star      |768            |2004-03-02T00:00:00.000Z
Vernor Vinge     |A Fire Upon the Deep|613            |1992-06-01T00:00:00.000Z
Frank Herbert    |Dune                |604            |1965-06-01T00:00:00.000Z

CLI de SQL

elasticsearch-sql-cli es un archivo de script en el directorio bin cuando ES está instalado, o se puede descargar por separado. Ejecutamos en el directorio ES

./bin/elasticsearch-sql-cli https://some.server:9200

Ingrese sql para consultar

sql> SELECT * FROM library WHERE page_count > 500 ORDER BY page_count DESC;
     author      |        name        |  page_count   | release_date
-----------------+--------------------+---------------+---------------
Peter F. Hamilton|Pandora's Star      |768            |1078185600000
Vernor Vinge     |A Fire Upon the Deep|613            |707356800000
Frank Herbert    |Dune                |604            |-144720000000

SQL a DSL

Escriba Kibana:

POST /_sql/translate
{
  "query": "SELECT * FROM library ORDER BY page_count DESC",
  "fetch_size": 10
}

Puede obtener la consulta DSL convertida:

{
  "size": 10,
  "docvalue_fields": [
    {
      "field": "release_date",
      "format": "epoch_millis"
    }
  ],
  "_source": {
    "includes": [
      "author",
      "name",
      "page_count"
    ],
    "excludes": []
  },
  "sort": [
    {
      "page_count": {
        "order": "desc",
        "missing": "_first",
        "unmapped_type": "short"
      }
    }
  ]
}

Debido a que se han generado las declaraciones relacionadas con la consulta, solo necesitamos modificar o no modificar adecuadamente sobre esta base para usar DSL felizmente.

Aquí detallamos en las declaraciones SQL compatibles con ES SQL y cómo evitar el uso indebido .

En primer lugar, debe comprender la correspondencia entre los términos SQL y los términos ES en las declaraciones SQL admitidas por ES SQL:

El soporte de sintaxis de ES SQL sigue principalmente el estándar ANSI SQL, y las declaraciones SQL admitidas incluyen consultas DML y algunas consultas DDL.
DDL consulta como: DESCRIBE table, SHOW COLUMNS IN tablepoco insípido, buscamos principalmente para la SELECT,Functioncompatibilidad con consultas DML.

SELECCIONE

La estructura gramatical es la siguiente:

SELECT [TOP [ count ] ] select_expr [, ...]
[ FROM table_name ]
[ WHERE condition ]
[ GROUP BY grouping_element [, ...] ]
[ HAVING condition]
[ ORDER BY expression [ ASC | DESC ] [, ...] ]
[ LIMIT [ count ] ]
[ PIVOT ( aggregation_expr FOR column IN ( value [ [ AS ] alias ] [, ...] ) ) ]

Representa la obtención de datos de fila de tablas 0-N. El orden de ejecución de SQL es:

  1. Obtenga todas FROMlas palabras clave para determinar el nombre de la tabla.

  2. Si hay WHEREcondiciones para filtrar todas las líneas no se cumplen.

  3. Si hay GROUP BYcondiciones, la agregación de paquetes; si hay HAVINGcondiciones, se filtran los resultados de la polimerización.

  4. El resultado obtenido en el paso anterior se select_exprcalcula para determinar los datos devueltos específicos.

  5. Si hay ORDER BYcondiciones, ha devuelto la clasificación de datos.

  6. Si hay una condición LIMITo TOP, se devolverá un subconjunto del resultado del paso anterior.

Hay dos diferencias con las cláusulas TOP [ count ]y el soporte de SQL, ES SQL de uso común PIVOT ( aggregation_expr FOR column IN ( value [ [ AS ] alias ] [, ...] ) ).
TOP [ count ]: Si SELECT TOP 2 first_name FROM empsignifica devolver dos datos como máximo, no se puede LIMITcompartir con condiciones.
PIVOTLa cláusula realizará la conversión de fila a columna de los resultados obtenidos por sus condiciones de agregación para operaciones posteriores. No he usado esto antes, así que no lo presentaré.

FUNCIÓN

Basándonos en el SQL anterior, podemos tener SQL para filtrar, agregar, ordenar y paginar. Pero necesitamos aprender más sobre el soporte FUNCTION en ES SQL para escribir SQL enriquecido con funciones de búsqueda, agregación y agrupación de texto completo.
Utilícelo para enumerar SHOW FUNCTIONSlos nombres de las funciones admitidas y sus tipos.

SHOW FUNCTIONS;

      name       |     type
-----------------+---------------
AVG              |AGGREGATE
COUNT            |AGGREGATE
FIRST            |AGGREGATE
FIRST_VALUE      |AGGREGATE
LAST             |AGGREGATE
LAST_VALUE       |AGGREGATE
MAX              |AGGREGATE
MIN              |AGGREGATE
SUM              |AGGREGATE
........

Analizamos principalmente las funciones comunes relacionadas con la agregación, agrupación y búsqueda de texto completo.

Función de coincidencia de texto completo

MATCH: Equivale a la búsqueda de coincidencias y múltiples coincidencias en DSL.

MATCH(
    field_exp,       --字段名称
    constant_exp,       --字段的匹配值
    [, options])       --可选项

Ejemplos de uso:

SELECT author, name FROM library WHERE MATCH(author, 'frank');

    author     |       name
---------------+-------------------
Frank Herbert  |Dune
Frank Herbert  |Dune Messiah
SELECT author, name, SCORE() FROM library WHERE MATCH('author^2,name^5', 'frank dune');

    author     |       name        |    SCORE()
---------------+-------------------+---------------
Frank Herbert  |Dune               |11.443176
Frank Herbert  |Dune Messiah       |9.446629

QUERY: Equivale a query_string en DSL.

QUERY(
    constant_exp      --匹配值表达式
    [, options])       --可选项

Ejemplos de uso:

SELECT author, name, page_count, SCORE() FROM library WHERE QUERY('_exists_:"author" AND page_count:>200 AND (name:/star.*/ OR name:duna~)');

      author      |       name        |  page_count   |    SCORE()
------------------+-------------------+---------------+---------------
Frank Herbert     |Dune               |604            |3.7164764
Frank Herbert     |Dune Messiah       |331            |3.4169943

SCORE(): Devuelve la relevancia de los datos de entrada y los datos devueltos.
Ejemplos de uso:

SELECT SCORE(), * FROM library WHERE MATCH(name, 'dune') ORDER BY SCORE() DESC;

    SCORE()    |    author     |       name        |  page_count   |    release_date
---------------+---------------+-------------------+---------------+--------------------
2.2886353      |Frank Herbert  |Dune               |604            |1965-06-01T00:00:00Z
1.8893257      |Frank Herbert  |Dune Messiah       |331            |1969-10-15T00:00:00Z

Función agregada

AVG(numeric_field) : Calcula el valor medio de los campos numéricos.

SELECT AVG(salary) AS avg FROM emp;

COUNT(expression): Devuelve el número total de datos de entrada, incluidos los datos cuyo valor es nulo correspondiente a field_name en COUNT ().
COUNT(ALL field_name): Devuelve el número total de datos de entrada, excluyendo los datos cuyo valor es nulo correspondiente a field_name.
COUNT(DISTINCT field_name): Devuelve el número total de valores correspondientes a field_name en los datos de entrada que no son nulos.
SUM(field_name): Devuelve la suma de los valores correspondientes al campo numérico field_name en los datos de entrada.
MIN(field_name): Devuelve el valor mínimo del valor correspondiente al campo numérico field_name en los datos de entrada.
MAX(field_name): Devuelve el valor máximo correspondiente al campo numérico field_name en los datos de entrada.

Función de agrupación

La función de agrupación aquí corresponde a la agrupación de depósitos en el DSL.

HISTOGRAM: La sintaxis es la siguiente:

HISTOGRAM(
           numeric_exp,    --数字表达式,通常是一个field_name
           numeric_interval    --数字的区间值
)

HISTOGRAM(
           date_exp,      --date/time表达式,通常是一个field_name
           date_time_interval      --date/time的区间值
)

Lo siguiente devuelve los datos de los nacimientos en las primeras horas de la mañana del 1 de enero de cada año:

ELECT HISTOGRAM(birth_date, INTERVAL 1 YEAR) AS h, COUNT(*) AS c FROM emp GROUP BY h;


           h            |       c
------------------------+---------------
null                    |10
1952-01-01T00:00:00.000Z|8
1953-01-01T00:00:00.000Z|11
1954-01-01T00:00:00.000Z|8
1955-01-01T00:00:00.000Z|4
1956-01-01T00:00:00.000Z|5
1957-01-01T00:00:00.000Z|4
1958-01-01T00:00:00.000Z|7
1959-01-01T00:00:00.000Z|9
1960-01-01T00:00:00.000Z|8
1961-01-01T00:00:00.000Z|8
1962-01-01T00:00:00.000Z|6
1963-01-01T00:00:00.000Z|7
1964-01-01T00:00:00.000Z|4
1965-01-01T00:00:00.000Z|1

Limitaciones de ES SQL

Debido a que ES SQL y ES DSL no están completamente emparejados funcionalmente, las limitaciones de SQL mencionadas en los documentos oficiales son:

Las consultas grandes pueden generar ParsingException

En la fase de análisis, las consultas extremadamente grandes ocuparán demasiada memoria. En este caso, el motor SQL de Elasticsearch abortará el análisis y arrojará un error.

Representación de campos de tipo anidado

SQL no admite campos de tipo anidado, solo se puede usar

[nested_field_name].[sub_field_name]

Este formulario se refiere a subcampos en línea.
Ejemplos de uso:

SELECT dep.dep_name.keyword FROM test_emp GROUP BY languages;

El campo de tipo anidado no se puede utilizar en la función escalar de dónde y ordenar por

Son como el siguiente error SQL de

SELECT * FROM test_emp WHERE LENGTH(dep.dep_name.keyword) > 5;

SELECT * FROM test_emp ORDER BY YEAR(dep.start_date);

No admite consultas simultáneas de varios campos anidados

Por ejemplo, los campos anidados nested_A y nested_B no se pueden utilizar al mismo tiempo.

Límite de paginación del campo interno anidado

Cuando la consulta de paginación tiene campos anidados, los resultados de la paginación pueden ser incorrectos. Esto se debe a que: la consulta de paginación en ES se produce en el documento anidado raíz, no en su campo interno.

El campo del tipo de palabra clave no admite el normalizador

No admite campos de tipo de matriz

Esto se debe a que un campo en SQL corresponde a un solo valor. En este caso, podemos usar la API de SQL a DSL descrita anteriormente para convertirlo en una instrucción DSL, solo use DSL para consultar.

Limitaciones de la clasificación agregada

  • El campo de clasificación debe ser un campo en el depósito de agregación. ES SQL CLI rompe esta limitación, pero el límite superior no puede exceder las 512 filas; de lo contrario, se lanzará una excepción durante la etapa de clasificación. Se recomienda usar con Limitcláusulas, como:

SELECT * FROM test GROUP BY age ORDER BY COUNT(*) LIMIT 100;
  • La condición de clasificación de la clasificación agregada no admite la función escalar ni las operaciones de operador simples. Los campos complejos después de la agregación (por ejemplo, que contienen funciones de agregación) no se pueden utilizar en las condiciones de clasificación.

Los siguientes son ejemplos de errores:

SELECT age, ROUND(AVG(salary)) AS avg FROM test GROUP BY age ORDER BY avg;

SELECT age, MAX(salary) - MIN(salary) AS diff FROM test GROUP BY age ORDER BY diff;

Limitaciones de las subconsultas

Si la subconsulta contiene GROUP BY or HAVINGo es más SELECT X FROM (SELECT ...) WHERE [simple_condition]complicada que esta estructura, es posible que no tenga éxito.

El campo de tipo de datos TIME no admite la condición GROUP BY y la función HISTOGRAM

Como la siguiente consulta es incorrecta:

SELECT count(*) FROM test GROUP BY CAST(date_created AS TIME);

SELECT HISTOGRAM(CAST(birth_date AS TIME), INTERVAL '10' MINUTES) as h, COUNT(*) FROM t GROUP BY h

Pero envolver el campo de tipo TIME como una función escalar para regresar es admitir GROUP BY, como:

SELECT count(*) FROM test GROUP BY MINUTE((CAST(date_created AS TIME));

Restricciones sobre los campos devueltos
Si un campo no está almacenado en la fuente, no se puede consultar. keyword, date, scaled_float, geo_point, geo_shapeEste tipo de campos de tales restricciones, porque no son de _sourcela devolución, sino de la docvalue_fieldsdevolución en.

No hay manera, pero la técnica se puede lograr; si no hay manera, termina con la técnica.

Bienvenidos a todos a seguir la cuenta pública de Java Way

Buen artículo, estoy leyendo ❤️

Supongo que te gusta

Origin blog.csdn.net/hollis_chuang/article/details/108675333
Recomendado
Clasificación