Создать индекс Elasticsearch с необязательным полем для сортировки - PullRequest
0 голосов
/ 27 октября 2019

Я использую SpringData Elasticsearch 3.2 и у меня есть документ с необязательным полем, который называется dueDate. Пользователи могут сортировать документы на основе поля dueDate, если оно заполнено.

Как только я создаю индекс и создаю документы без dueDate, я получаю исключение, говорящее о том, что в индексе при попытке перечисления нет поля dueDateдокументы. Если я создаю индекс и создаю документы со сроком исполнения, список документов работает как положено.

Есть ли способ заставить индекс (желательно с помощью Java-аннотации) иметь поле dueDate, даже если значение равно нулю, или перечислить документы без исключения?

Ответы [ 2 ]

0 голосов
/ 28 октября 2019

Какого типа ваше поле dueDate? И какой маппер вы используете - на основе Джексона DefaultEntityMapper или ElasticsearchEntityMapper?

Я бы порекомендовал использовать последний и определить свойство в вашем классе с помощью следующей аннотации (изменив шаблон нанеобходимый формат):

@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "YYYYMMDD")
private String dueDate;

Если вы используете репозитории Spring Data Elasticsearch, это создаст сопоставление при создании индекса репозиторием при запуске. В противном случае вы можете использовать метод ElasticsearchOperations.putMapping(Class<T>) или одну из его перегрузок, чтобы записать отображение в индекс.

0 голосов
/ 27 октября 2019
  1. Необходимо создать сопоставление перед индексацией документов. Вы по-прежнему сможете индексировать документы, если в отображении отсутствует поле.

  2. Использовать сценарии при сортировке (его производительность будет меньше, чем в варианте 1).

{
  "query": {
    "match_all": {}
  },
  "sort" : {
        "_script" : {
            "type" : "number",
            "script" : {
                "lang": "painless",
                "source": "if(doc['dueDate'].size()!=0){doc['dueDate'].value.getMillis()}"
            },
            "order" : "desc"
        }
    }
}

if (doc ['dueDate']. Size ()! = 0) -> проверить, существует ли поле.

doc ['dueDate']. Value.getMillis ()- преобразует дату в миллисекунды (число)

EDIT1:

GET index27/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [{
        "_script": {
            "type": "number",
            "script": {
                "lang": "painless",
                "inline": "if(doc['dueDate'].size()!=0) { return doc['dueDate'].value.getMillis();} else{  new Date().getTime();}"
            },
            "order": "asc"
        }
    }]
}

new Date (). getTime () выдаст текущую дату. Используется в случае, если вам нужны документы с датой исполнения, которая должна быть наверху

...