Encuentra documentos con valor de cadena vacía en elasticsearch

He intentado filtrar con elasticsearch solo los documentos que contienen una cadena vacía en su cuerpo. Hasta ahora no estoy teniendo suerte.

Antes de continuar, debo mencionar que ya he probado las muchas “soluciones” diseminadas por Interwebz y StackOverflow.

Entonces, debajo está la consulta que estoy tratando de ejecutar, seguida de sus contrapartes:

{ "query": { "filtered":{ "filter": { "bool": { "must_not": [ { "missing":{ "field":"_textContent" } } ] } } } } } 

También intenté lo siguiente:

  { "query": { "filtered":{ "filter": { "bool": { "must_not": [ { "missing":{ "field":"_textContent", "existence":true, "null_value":true } } ] } } } } } 

Y lo siguiente:

  { "query": { "filtered":{ "filter": { "missing": {"field": "_textContent"} } } } } 

Ninguno de los anteriores funcionó. Obtengo un conjunto de resultados vacío cuando sé con certeza que hay registros que contienen un campo de cadena vacío.

Si alguien puede brindarme alguna ayuda, le estaré muy agradecido.

¡Gracias!

Si está utilizando el analizador predeterminado ( standard ), no hay nada que analizar si es una cadena vacía. Entonces necesita indexar el campo textualmente (no analizado). Aquí hay un ejemplo:

Agregue una asignación que indexará el campo declarado, si necesita una copia simbólica del campo también puede usar un tipo de campo múltiple .

 PUT http://localhost:9200/test/_mapping/demo { "demo": { "properties": { "_content": { "type": "string", "index": "not_analyzed" } } } } 

A continuación, indexe un par de documentos.

 /POST http://localhost:9200/test/demo/1/ { "_content": "" } /POST http://localhost:9200/test/demo/2 { "_content": "some content" } 

Ejecuta una búsqueda:

 POST http://localhost:9200/test/demo/_search { "query": { "filtered": { "filter": { "term": { "_content": "" } } } } } 

Devuelve el documento con la cadena vacía.

 { took: 2, timed_out: false, _shards: { total: 5, successful: 5, failed: 0 }, hits: { total: 1, max_score: 0.30685282, hits: [ { _index: test, _type: demo, _id: 1, _score: 0.30685282, _source: { _content: "" } } ] } } 

Incluso con el analizador predeterminado puede hacer este tipo de búsqueda: use un filtro de script , que es más lento pero puede manejar la cadena vacía:

 curl -XPOST 'http://localhost:9200/test/demo/_search' -d ' { "query": { "filtered": { "filter": { "script": { "script": "_source._content.length() == 0" } } } } }' 

Devolverá el documento con una cadena vacía como _content sin una asignación especial

Como señala @js_gandalf, esto está en desuso para ES> 5.0. En su lugar, debe usar: query-> bool-> filter-> script como en https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html

para encontrar la cadena vacía de un campo en su documento, es muy relevante para la asignación del campo; en otras palabras, su configuración de index / analyzer .

Si su índice no está not_analyzed , lo que significa que el token es solo la cadena vacía, puede usar la búsqueda por term para encontrarlo, de la siguiente manera:

{"from": 0, "size": 100, "query":{"term": {"name":""}}}

De lo contrario, si se analyzed configuración del index y creo que la mayoría de los analizadores tratarán la cadena vacía como valor nulo, entonces puede usar el filtro para encontrar la cadena vacía.

{"filter": {"missing": {"existence": true, "field": "name", "null_value": true}}, "query": {"match_all": {}}}

aquí está el script gist al que puede hacer referencia: https://gist.github.com/hxuanji/35b982b86b3601cb5571

Por cierto, verifico los comandos que me proporcionó, parece que NO QUIERE el documento de cadena vacío. Y todos mis comandos anteriores son solo para encontrarlos, así que simplemente póngalo en must_not parte de la consulta de bool estaría bien. Mi ES es 1.0.1.


Para ES 1.3.0, actualmente la esencia que proporcioné no puede encontrar la cadena vacía. Parece que se ha informado: https://github.com/elasticsearch/elasticsearch/issues/7348 . Esperemos y veamos cómo va.

De todos modos, también proporciona otro comando para encontrar

{“consulta”: {“filtrado”: {“filtro”: {“no”: {“filtro”: {“rango”: {“nombre”: {}}}}}}}}

name es el name del campo para encontrar la cadena vacía. Lo he probado en ES 1.3.2.

Para aquellos de ustedes que usan el elástico de búsqueda 5.2 o superior, y todavía estancado. La manera más fácil es reindexar sus datos correctamente con el tipo de palabra clave. Entonces todas las búsquedas de valores vacíos funcionaron. Me gusta esto:

 "query": { "term": {"MY_FIELD_TO_SEARCH": ""} } 

En realidad, cuando vuelvo a indexar mi base de datos y vuelvo a ejecutar la consulta. Funcionó =)

El problema era que mi campo era tipo: texto y NO una palabra clave. Cambiado el índice a palabra clave y reindexado:

 curl -X PUT https://username:password@host.io:9200/mycoolindex curl -X PUT https://user:pass@host.io:9200/mycoolindex/_mapping/mycooltype -d '{ "properties": { "MY_FIELD_TO_SEARCH": { "type": "keyword" }, }' curl -X PUT https://username:password@host.io:9200/_reindex -d '{ "source": { "index": "oldindex" }, "dest": { "index": "mycoolindex" } }' 

Espero que esto ayude a alguien que estaba tan atrapado como yo estaba encontrando esos valores vacíos.

Estoy usando Elasticsearch 5.3 y estaba teniendo problemas con algunas de las respuestas anteriores.

El siguiente cuerpo funcionó para mí.

  { "query": { "bool" : { "must" : { "script" : { "script" : { "inline": "doc['city'].empty", "lang": "painless" } } } } } } 

Nota: es posible que necesite habilitar los datos de campo para campos de texto, está deshabilitado de manera predeterminada. Aunque leería esto: https://www.elastic.co/guide/en/elasticsearch/reference/current/fielddata.html antes de hacerlo.

Para habilitar los datos de campo para un campo, por ejemplo, “ciudad” en el índice “empresa” con el nombre de tipo “registro”, necesita:

 PUT business/_mapping/record { "properties": { "city": { "type": "text", "fielddata": true } } } 

Para los campos nesteds, use:

 curl -XGET "http://localhost:9200/city/_search?pretty=true" -d '{ "query" : { "nested" : { "path" : "country", "score_mode" : "avg", "query" : { "bool": { "must_not": { "exists": { "field": "country.name" } } } } } } }' 

NOTA: la ruta y el campo juntos constituyen para la búsqueda. Cambie según sea necesario para que trabaje.

Para campos regulares:

 curl -XGET 'http://localhost:9200/city/_search?pretty=true' -d'{ "query": { "bool": { "must_not": { "exists": { "field": "name" } } } } }' 

No logré buscar cadenas vacías en un campo de texto. Sin embargo, parece funcionar con un campo de tipo palabra clave. Entonces sugiero lo siguiente:

  delete /test_idx put test_idx { "mappings" : { "testMapping": { "properties" : { "tag" : {"type":"text"}, "content" : {"type":"text", "fields" : { "x" : {"type" : "keyword"} } } } } } } put /test_idx/testMapping/1 { "tag": "null" } put /test_idx/testMapping/2 { "tag": "empty", "content": "" } GET /test_idx/testMapping/_search { "query" : { "match" : {"content.x" : ""}}} } } 

Debe activar el indexador de palabras clave agregando .content a su nombre de campo. Dependiendo de cómo se configuró el índice original, lo siguiente “simplemente funciona” para mí usando AWS ElasticSearch v6.x.

GET /my_idx/_search?q=my_field.content: “”

Si no quiere o no puede volver a indexar, hay otra forma. 🙂

Puede usar el operador de negación y un comodín para hacer coincidir cualquier cadena que no esté en blanco *

 GET /my_index/_search?q=!(fieldToLookFor:*)