Использование подзапроса в спящем запросе FullTextEntityManager - PullRequest
0 голосов
/ 28 мая 2019

Я пытаюсь изменить какой-то код с помощью спящего режима FullTextEntityManager.По сути, это работает в настоящее время, но я хотел бы ограничить результаты подмножеством записей в таблице (самой последней из данного типа).

Так, например, базовый запрос данных для поиска может быть чем-то вроде этих строк (только для демонстрации, я не анализировал это!)

SELECT name, address 
FROM Persons p
WHERE p.name = sq.name
FROM 
(SELECT name, max(datemodified)
 FROM Persons 
  GROUP BY name) sq

В настоящее время код Java простовыбор из необработанной таблицы (по сути, это то, что я думаю, для опции forEntity)

FullTextEntityManager ftem = Search.getFullTextEntityManager(getEntityManager());

SearchFactory sf= ftem.getSearchFactory();
QueryContextBuilder qcb = sf.buildQueryBuilder();
QueryBuilder qb= qcb.forEntity(entityClass).get();

//processSearchExpression builds a lucene style full text search
org.apache.lucene.search.Query q= processSearchExpression();

FullTextQuery ftq= ftem.createFullTextQuery(q, entityClass);

Так что, по сути, я думаю, что я поместил основы там довольно точно.Что я не могу понять, так это как добавить подзапрос или что-то похожее, чтобы я мог просто запрашивать самые последние записи каждого типа?

1 Ответ

1 голос
/ 29 мая 2019

На данный момент самое простое решение для объединения запросов ORM с поисковыми запросами состоит в том, чтобы добавить к вашему поисковому запросу условие для фильтрации по идентификатору.

FullTextEntityManager ftem = Search.getFullTextEntityManager(getEntityManager());

SearchFactory sf= ftem.getSearchFactory();
QueryBuilder qb= sf.buildQueryBuilder().forEntity(entityClass).get();

BooleanJunction<?> idJunction = qb.bool();
for (Long id : listIdsYouWant()) {
   idJunction.must(qb.match().onField("id").matching(id).createQuery());
}

org.apache.lucene.search.Query q = qb.bool()
   //processSearchExpression builds a lucene style full text search
    .must(processSearchExpression())
    .filteredBy(idJunction.createQuery)
    .createQuery();

FullTextQuery ftq= ftem.createFullTextQuery(q, entityClass);

Если это не вариант, вам следует поискатьспособ индексировать данные, необходимые для воспроизведения SQL-запроса, с использованием полнотекстового запроса.

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

Одно решениевместо этого будет использовать Hibernate Envers, который в прошлый раз, когда я проверял, полностью совместим с Hibernate Search.См. http://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#envers

Другое решение - назначить один и тот же идентификатор документа всем лицам, которых вы считаете идентичными.Таким образом, в индексе будет только один человек: последний, который был изменен.См. https://docs.jboss.org/hibernate/search/5.11/reference/en-US/html_single/#id-annotation Однако вы можете столкнуться с некоторыми проблемами при получении объекта, соответствующего данному документу, так как несколько объектов будут совпадать.Вот почему лучше использовать Envers.

...