Обычно это происходит, когда объекты присутствуют в индексе, но не в базе данных (больше).В вашем случае первые 10 результатов появляются в вашем индексе, но не в вашей базе данных.
Причиной такого поведения является то, что Elasticsearch «почти в реальном времени»: после того, как мы внесем изменения в индекс,изменения займут некоторое время (обычно несколько секунд), пока они не будут видны в результатах поиска.Поэтому, если вы просто удалили сущности за несколько миллисекунд до этого, состояние индекса может «отставать» от состояния базы данных.
Если вы уверены, что сущности все еще существуют в базе данных, возможно, существует проблема с отображением идентификатораили с выбранной вами конфигурацией запроса.Пожалуйста, покажите нам код класса Person
и укажите значение, которое вы задали для свойств hibernate.search.query.object_lookup_method
и hibernate.search.query.database_retrieval_method
, если вы не используете значения по умолчанию.
Решение в тестах
Если это проблема при тестировании, вы можете установить hibernate.search.default.elasticsearch.refresh_after_write
на true
. Вы не должны устанавливать это в производстве , поскольку это резко снизит производительность индексации.
Решение в производстве
Если это проблема в производстве, ивам нужно решить это эффективно, это будет сложнее.Единственное решение, которое я могу придумать, - это перейти от нумерации страниц по индексам к нумерации страниц по ключам.Однако вы потеряете возможность переходить на страницу напрямую и не сможете отсортировать результаты любым удобным для вас способом.
Вам потребуется найти строго монотонный ключ в ваших результатах, т. е. поле, которое гарантированно будет уникальным для каждого результата и всегда будет увеличиваться (или всегда уменьшаться) при переходе к следующему результату.Идентификатор будет хорошим кандидатом, если вы сортируете по идентификатору.Дата создания тоже может работать, если она достаточно точна, и вы сортируете по этой дате создания.
Этот ключ будет использоваться для игнорирования предыдущих страниц: клиент не отправит номер страницы на сервер, он будетотправьте последнее значение для «строго монотонного» ключа, и вы просто добавите в свой запрос такой предикат: queryBuilder.range().onField("myKey").above(<the last value for the key in the previous page>).createQuery()
.
Затем вместо непосредственного возврата результатов вашего запроса вы вместо этого выполнитезапрос несколько раз, накапливая результаты в списке, пока он не достигнет соответствующего размера страницы (или пока getResultSize
не вернет 0).
РЕДАКТИРОВАТЬ: другое решение, возможно, более простое, но это только уменьшит вероятностьэту проблему, не удаляйте ее полностью.
Вы можете убедиться, что Elasticsearch обновляет свои индексы чаще, задав для index.refresh_interval
значение, которое короче значения по умолчанию (1s
) для всех индексов.Обратите внимание, что это может очень плохо повлиять на производительность кластера Elasticsearch в зависимости от того, как часто вы пишете в кластер.
Чтобы применить настройку ко всем индексам, самое простое решение - создать шаблоны индексов до того, как Hibernate Search создаст индексы.