Найти поля содержащие пустую строку и удалить

Собственно subj. Хочу найти документы в которые поле пустое и удалить его совсем.

  1. Вариант:
{
  "query": { 
    "nested":{
      "path":"body2",
      "query":{
        "bool": { 
          "filter": { 
          "exists":{"field":"body2.txt"} 
          }, 
          "must_not": { 
            "wildcard": { "body2.txt": "*" } 
          }
        }
      }
    }
  }
}

Неподходит тем, что если поле например содержит только стоп-слова оно сюда попадет. Но при следующей переиндексации и другом мапипинге какие то слова могут оказаться нужными.

  1. Вариант reindex со скриптом - сделать можно, что угодно, но очень долго.

Пытался еще сделать через update со сриптом, но ES ругается , что поле текстовое и нет FieldData.

Есть еще варианты?

С точки зрения индекса строка состоящая из сплошных шумовых слов и пустая строка - это одно и то же. Поэтому если это поле еще как-то не проиндексировано, но в индексе информации об этом отличии просто нет. Это значит, что нам в любом случае получать source для записей с пустыми шумовыми словами и проверять ее. То есть как-то так:

DELETE test


PUT test
{
  "mappings": {
    "properties": {
      "text": {
        "type": "text",
        "analyzer": "english"
      }
    }
  }
}

PUT test/_doc/only_stop_words
{
  "text": "to be or not to be"
}

PUT test/_doc/not_empty
{
  "text": "that is the question"
}

PUT test/_doc/empty
{
  "text": ""
}

PUT test/_doc/null
{
  "text": null
}

PUT test/_doc/does_not_exist
{

}


POST test/_update_by_query
{
  "script": {
    "source": """
      if(ctx._source.text.length() > 0) {
        ctx.op = "noop"
      } else {
        ctx._source.remove('text')
      }
      
      """,
    "lang": "painless"
  },
  "query": {
    "bool": {
      "filter": {
        "exists": {
          "field": "text"
        }
      },
      "must_not": {
        "wildcard": {
          "text": "*"
        }
      }
    }
  }
}

POST test/_search

Да, в общем то логично, что если поле не проиндексировано надо работать на уровне _source. :slight_smile:
Примерно так и сработало, правда не с первого раза.
Запрос якобы что-то делал, но при проверке все документы остались такими же как есть.

{
  "took" : 1204280,
  "timed_out" : false,
  "total" : 2033165,
  "updated" : 1934233,
  "deleted" : 0,
  "batches" : 2034,
  "version_conflicts" : 0,
  "noops" : 98932,
  "retries" : {
    "bulk" : 0,
    "search" : 0
  },
  "throttled_millis" : 0,
  "requests_per_second" : -1.0,
  "throttled_until_millis" : 0,
  "failures" : [ ]
}

Видимо у меня нюанс в nested. Я удалил весь nested т.к. в этом случае он весь ненужен.

{ 
  "script": { 
    "source": "if(ctx._source.body2.txt.length() > 0) { ctx.op = \"noop\" } else { ctx._source.remove('body2') } ",
    "lang": "painless"
  },
  "query": { 
    "nested":{ 
      "path":"body2", 
      "query":{ 
        "bool": { 
          "filter": { 
            "exists":{"field":"body2.txt"} 
          }, 
          "must_not": { 
            "wildcard": { "body2.txt": "*" } 
          } 
        } 
      } 
    } 
  } 
}

Спасибо!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.