Объединение filter и function_score — эластичный поиск не будет вычислять оценку?

#elasticsearch #search

#elasticsearch #Поиск

Вопрос:

У меня есть posts индекс, и я хочу

а) Отфильтровывать все сообщения по дате, т.Е. Возвращать сообщения, созданные только до заданного date

б) Применить function_score к результатам.

Я придумал этот запрос, который выглядит примерно так:

 get posts/_search
{
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "filter": [
            {
              "range": {
                "created_at": {
                  "lte": "2020-09-12T17:23:00Z"
                }
              }
            }
          ]
        }
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "likes",
            "factor": 0.1,
            "modifier": "ln1p",
            "missing": 1
          }
        }
      ],
      "score_mode": "sum"
    }
  },
  "from": 0,
  "size": 10
}
  

Однако проблема в том, что эластичный поиск НЕ применяет оценку к результатам, все документы имеют 0.0 оценку. Я могу «обмануть» ES, переместив фильтр в функции, и тогда это сработает, но я чувствую, что это не оптимально, есть идеи, почему приведенный выше запрос не вернет оценки?

Пример «читерского» запроса, который вычисляет оценки для каждого документа:

 get posts/_search
{
  "query": {
    "function_score": {
      "functions": [
        {
          "filter": {
            "range": {
              "created_at": {
                "lte": "2020-09-12T17:22:58Z"
              }
            }
          },
          "weight": 100
        },
        {
          "gauss": {
            "created_at": {
              "origin": "2020-09-12T17:22:58Z",
              "scale": "1h",
              "decay": 0.95
            }
          }
        },
        {
          "field_value_factor": {
            "field": "likes",
            "factor": 0.1,
            "modifier": "ln1p",
            "missing": 1
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 10
}
  

Ответ №1:

Фильтр не влияет на оценку. это просто 0 ИЛИ 1. Чтобы иметь возможность влиять на оценку с помощью запроса function_score, вы должны использовать функцию, которая вычисляет оценку (совпадение, совпадение_фраза, географический запрос и т. Д.) Вы можете получить более подробную информацию о контексте в документации

field_value_factor влияет на существующую оценку, но в вашем первом запросе у вас нет никакой оценки на данном этапе, так как это почти то же самое, что и при заказе на аналогичное количество.

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