Фильтр вложенной сортировки в elasticsearch

У меня есть документ с вложенной структурой, вложенный объект имеет assignment_name и due_date:

Отображение

{
  "goal": {
    "mappings": {
      "doc": {
        "properties": {
          "title": {
            "type": "keyword"
          },
          // lot's of other fields here ...
          "steps": {
            "type": "nested",
            "properties": {
              "assignment_name": {
                "type": "keyword"
              },
              "due_date": {
                "type": "date"
              }
              // lots of other fields here
            }
          }
        }
      }
    }
  }
}

Я бы хотел:

  1. Отфильтровать все документы, которые имеют определенное имя_назначения (например, user_a)
  2. Отсортируйте результат по ближайшей дате выполнения, не принимая во внимание другие назначения.

Этот запрос дает мне случайный результат (без сортировки):

{  
   "query":{  
      "bool":{  
         "filter":[  
            {  
               "nested":{  
                  "path":"steps",
                  "query":{  
                     "term":{  
                        "steps.assignment_name":"user_a"
                     }
                  }
               }
            }
         ]
      }
   },
   "sort":[  
      {  
         "steps.due_date":{  
            "order":"asc",
            "nested":{  
               "path":"steps",
               "filter":{  
                  "term":{  
                     "steps.assignment_name":"user_a"
                  }
               }
            }
         }
      }
   ],
   "from":0,
   "size":25
}
1
0
1 792
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Во-первых, вам нужно убедиться, что тип данных для поля stepsnested. Затем вы должны использовать вложенная сортировка для сортировки документов на основе вложенного поля документа.

Запрос будет таким:

{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "steps",
            "query": {
              "term": {
                "steps.assignment_name": "user_a"
              }
            }
          }
        }
      ]
    }
  },
  "sort": [
    {
      "steps.due_date": {
        "order": "asc",
        "nested": {
          "path": "steps",
          "filter": {
            "term": {
              "steps.assignment_name": "user_a"
            }
          }
        }
      }
    }
  ]
}

Уловка выше заключается в использовании того же фильтра сортировки, который используется в основном запросе для фильтрации документов. Это гарантирует, что при сортировке документов будет учитываться правильное значение поля вложенного документа.

Хм. Это не работает. Я получаю нулевые результаты с постфиксом .keyword и случайные (не отсортированные) результаты без него.

shredding 26.06.2019 12:01

@shredding Можете ли вы добавить сопоставление индекса с вопросом?

Nishant 26.06.2019 12:04

Фактическое сопоставление несколько отличается (поскольку проблему было проще объяснить с помощью комментариев, но я буду обновлять соответственно) в секунду!

shredding 26.06.2019 12:06

Обновлено. Теперь я скопировал сопоставление и фактический запрос. Извините, что мне не удалось привести упрощенный пример.

shredding 26.06.2019 12:14

Есть ли вероятность того, что один документ имеет более одного вложенного документа, где steps.assignment_name имеет значение как user_a?

Nishant 26.06.2019 12:20

Это на самом деле идея. У него может быть n шагов с различными назначениями, и я хочу, чтобы был следующий.

shredding 26.06.2019 12:21

Это действительно странно, так как это не случайно. У меня есть модульный тест, и он работает примерно 19 из 20 раз.

shredding 26.06.2019 12:23

Ладно, вроде не случайно. Я увеличил команду sleep после фиксации индекса до одной секунды, и теперь она работает. Так что может быть просто проблема с синхронизацией в моем модульном тесте. Спасибо большое.

shredding 26.06.2019 12:25

... хм. или нет, он ломается примерно каждые 1/30, но, возможно, это проблема синхронизации.

shredding 26.06.2019 12:28

Похоже, вы запрашиваете до обновления индекса.

Nishant 26.06.2019 12:39

Есть ли способ узнать, обновлен ли индекс? Сейчас я использую flush_index и pythons sleep.

shredding 26.06.2019 12:42

Посмотрите на обновить индекс. Это следует использовать с осторожностью для производственного кластера. Хотя его можно использовать для dev/test env и UT.

Nishant 26.06.2019 12:45

Да, в производстве у меня все в порядке с задержкой. Я добавил 1 секунду сна с последующим обновлением и смог запустить модульный тест 100 раз подряд. Спасибо за вашу помощь.

shredding 26.06.2019 12:49

Как включить другие критерии фильтрации для сортировки?

Md. Arafat Al Mahmud 23.02.2022 15:04

Другие вопросы по теме