Запустите подзапрос для каждого из отфильтрованных документов elasticsearch.

У меня есть индекс с именем сотрудников со следующей структурой:

{
id: integer,
name: text,
age: integer,
cityId: integer,
resumeText: text           <--------- parsed resume text
}

Я хочу искать сотрудников по определенным критериям, например, возраст > 40 лет, текст резюме содержит определенный навык или сотрудник принадлежит к определенному городу и т. д., и у меня есть следующий запрос для до сих пор требования:

{
query:{
bool:{
should:[
{
term:{
cityId:2990
},
{
match:{
resumeText:"marketing"
},
{
match:{
resumeText:"critical thinking"
}}}
],
filter:{
range:{
age:{
gte:40
}}}}}
}

Это дает мне ожидаемые результаты, но я также хочу знать среди возвращенных документов/сотрудников те, чье резюме содержит упомянутые навыки. например, в ответе я хочу получить документы, в которых упоминается, что этот документ соответствует критическому мышлению, этот сотрудник соответствует обоим навыкам, а этот сотрудник не соответствует ни одному навыку (поскольку он был возвращен на основе других фильтров)

Какие изменения мне нужно сделать, чтобы получить желаемые результаты:

  • может сборка поможет?
  • Можем ли мы создать сценарий для КАЖДОГО отфильтрованного документа для вычисления желаемого результата (подзапрос для каждого документа)?
  • любой другой подход?

person Kamboh    schedule 20.06.2020    source источник
comment
Не могли бы вы проголосовать/принять/оба, если ответ ниже полезен?   -  person Gibbs    schedule 28.06.2020


Ответы (1)


Да, вы можете использовать агрегацию.

Перейти сюда

Вы можете группировать, например, сколько резюме соответствует каждому навыку, который вы ищете.

GET employees/_search
{
  "size": 0,
  "aggs" : {
    "messages" : {
      "filters" : {
        "filters" : {
          "marketing_resume_count" :   { "match" : { "resumeText" : "marketing"   }},
          "thinking_resume_count" : { "match" : { "resumeText" : "thinking" }}
        }
      }
    }
  }
}

Чтобы расширить ваш вариант использования:

Вы можете добавить раздел query к запросу, как показано ниже.

GET employees/_search
    {
      "size": 0,
      "query":{
        "match":{
           "region":"AM"
        }
      },
      "aggs" : {
        "messages" : {
          "filters" : {
            "filters" : {
              "marketing_resume_count" :   { "match" : { "resumeText" : "marketing"   }},
              "thinking_resume_count" : { "match" : { "resumeText" : "thinking" }}
            }
          }
        }
      }
    }

Вы можете использовать запрос range для обработки условий gte и let. Вы можете сослаться на это для примера запроса диапазона . Его можно использовать вместо раздела query.

person Gibbs    schedule 20.06.2020
comment
спасибо @Gibbs, этот запрос дает мне агрегацию на родительском уровне фильтров, я не могу сопоставить эту информацию с каждым совпадающим документом, он дает общий счет, например marketing_resume_count:{ "doc_count" : 2 }, для всех совпадающих документов, где я хочу знать, какие документы, в частности, совпали этот поиск также, мы можем сделать это? или мы можем добавить соответствующие идентификаторы документов к вышеуказанному запросу? - person Kamboh; 20.06.2020
comment
Да, вы можете сделать это с помощью TopHits - person Gibbs; 28.06.2020