Elastic Search - фильтр данных, которые соответствуют значению вместе с типом данных - PullRequest
0 голосов
/ 26 апреля 2019

Я использую ES 5.7 от AWS.Существует список объектов, хранящихся в кластере упругого поиска. Каждый объект имеет одно состояние поля, значение которого является целым числом, но из-за одной программной ошибки индексатора для некоторых объектов значение состояния сохраняется в виде текста вместо целого числа.Мне нужно отфильтровать объекты с помощью запроса bool, для которого статус имеет текст.

Я использовал запрос ниже для фильтрации данных.

пример данных

{  
   "took":22,
   "timed_out":false,
   "_shards":{  
      "total":16,
      "successful":16,
      "failed":0
   },
   "hits":{  
      "total":3208,
      "max_score":1,
      "hits":[  
         {  
            "_index":"entity-data",
            "_type":"account",
            "_id":"b7b46c",
            "_score":1,
            "_source":{  
               "status":"3"
            }
         },
         {  
            "_index":"entity-data",
            "_type":"account",
            "_id":"b7b46",
            "_score":1,
            "_source":{  
               "status":3
            }
         }
      ]
   }
}

запрос boolиспользуется для фильтрации на основе статуса

{  
   "query":{  
      "bool":{  
         "filter":[  
            {  
               "term":{  
                  "status": "3"
               }
            }
         ]
      }
   }
}

Here "status": "3" and "status": 3 is providing same result. 

Мне нужно отфильтровать данные, где «статус»: «3».

Любое предложение будет полезно.Заранее спасибо.

1 Ответ

1 голос
/ 27 апреля 2019

Ваш сценарий не работает, поскольку отображение поля будет иметь тип long, и при выполнении поиска с использованием сценария, который вы написали, он смотрит только на инвертированный индекс типа long.

Вы можетеиспользуйте безболезненно скрипт для доступа к значениям документа и поиска всех строковых значений.Скрипт проверяет тип данных поля status и возвращает true только для строкового типа.Следовательно, он вернет все документы, содержащие строковые значения.

PUT t1/doc/1
{
   "status": 3
}

PUT t1/doc/2
{
   "status": "3"
}



GET t1/_search
{
    "query": {
        "bool" : {
            "filter" : {
                "script" : {
                    "script" : {
                        "inline": "if(params._source.status instanceof String) return true;",
                        "lang": "painless"
                     }
                }
            }
        }
    }
}

Вывод:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0,
    "hits": [
      {
        "_index": "t1",
        "_type": "doc",
        "_id": "2",
        "_score": 0,
        "_source": {
          "status": "3"
        }
      }
    ]
  }
}

Дополнительная информация:

Если вы хотите измените все эти строковые значения на long , вы можете reindex в новый индекс и использовать скрипт для манипулирования значениями.

//Create new index
PUT t2

//reindex from t1 to t2 and change string to integer
POST _reindex
{
  "source": {
    "index": "t1"
  },
  "dest": {
    "index": "t2"
  },
  "script": {
    "lang": "painless",
    "inline": "if(ctx._source.status instanceof String){ctx._source.status = Integer.parseInt(ctx._source.status)}"
  }
}
...