etspring
@etspring
Начитанное быдло

Как осуществить фильтрацию значений поля в результатах выдачи в ElasticSeatch?

Доброго времени суток.

Немного пояснений.
Есть индекс, содержащий поля first_name, last_name, working_shifts - имя, фамилия и даты рабочих смен соответственно.
Каждая запись содержит уникальную пару first_name + last_name

В индексе есть запись
{"first_name": "Ivan", "last_name": "Ivanov", "workings_shifts": ["2022-02-01", "2022-02-04", "2022-02-05"]}


Каким образом можно получить working_shifts по Иванову Ивану, за определенный период?
Например за "gt": "2022-01-20", "lt": "2022-02-04" ?

Индекс:
{
  "employees": {
    "mappings": {
      "properties": {
        "first_name": { "type": "keyword" },
        "last_name": { "type": "keyword" },
        "working_shifts": { "type": "date" }
      }
    }
  }
}


Получаю запись по Ivan Ivanov
"size": 1,
  "body": {
    "query": {
      "bool": {
        "must": [
          { "match": { "first_name": { "query": "Ivan" } } },
          { "match": { "last_name": { "query": "Ivanov" } } }
        ]
      }
    },
    "fields": [
      {
        "field": "working_shifts",
      }
    ],
    "_source": false
  }


А каким образом к этому единственному результату применить диапазон, указанный выше?
{"gt": "2022-01-20", "lt": "2022-02-04"}
Чтобы осталось только:
{"working_shifts": ["2022-02-01",]}

Чтение документации в части Docvalue fields / Stored fields результатов не дало ;(
post_filter удаляет/оставляет целиком запись,
"post_filter": {
     "range":{
        "working_shifts":{
            "gte": "2022-01-01",
            "lte": "2022-02-03"
        }
      }
}


Заранее спасибо за ответ.

UPD:
Собственно сделал вот так, но наверняка ведь есть способ проще
"script_fields": {
      "Days": {
        "script": {
          "inline": """
          def fromTime = 1645218000;
          def days = [];
          for ( int i = 0; i < params['_source'].working_shifts.size(); i++ ) {
            if (params['_source'].working_shifts[i] > fromTime) {
              Date date = new java.util.Date(params['_source'].working_shifts[i]*1000L);
              SimpleDateFormat sdf = new java.text.SimpleDateFormat('yyyy-MM-dd');
              String formattedDate = sdf.format(date);
              days.add(formattedDate);
            }
          }
          return days;
          """
        }
      }
    }

Даты специально к unixtime приводятся, тк внутри эластика судя по всему невозможно сравнение дат:
Cannot apply [>] operation to types [java.util.Date] and [java.util.Date]
  • Вопрос задан
  • 45 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы