Hibernate поиск нескольких объектов - PullRequest
0 голосов
/ 06 июня 2018

Можно ли искать несколько объектов по одному и тому же ключевому слову, отфильтровывая каждый тип с помощью определенного фильтра и получая их в единый список?

Например, наличие объектов, заводчиков и животных и поиск их данных дляТермины "Бостон терьер".После этого селекционеры фильтруются по местоположению и животные по видам, и возвращается один список, содержащий как животных, так и селекционеров.

Затем этот список можно урезать, чтобы включить нумерацию результатов в интерфейсе веб-приложения:

        // FullTextQuery ftq = .... definiing and filtering the query

        int numResults = ftq.getResultSize();
        ftq.setFirstResult((pageNum-1)*numPerPage);
        ftq.setMaxResults(numPerPage);

        List<Object> results = ftq.getResultList();

1 Ответ

0 голосов
/ 07 июня 2018

Предполагая, что вы не заботитесь об отношениях между заводчиками и животными и просто хотите искать животных ИЛИ заводчиков: да, вы можете.

Но есть некоторые условия:

  • поля, к которым вы будете применять ваш термин-фильтр "Бостон-терьер", должны быть сконфигурированы точно таким же образом в классе Animal и в классе Breeder: в частности, в том же анализаторе.В противном случае результаты вашего поиска могут быть противоречивыми.Поля не обязательно должны существовать в обоих индексах: фильтрация по полям "animalName" и "breederName" должна работать нормально.
  • поле местоположения, которое вы хотите использовать для фильтрации селекционеров по местоположению не должно бытьсуществует в классе Animal.В противном случае, животные будут также отфильтрованы по местоположению.
  • поле вида, которое вы хотите использовать для фильтрации животных по видам , не должно существовать в классе Breeder.В противном случае селекционеры также будут отфильтрованы по видам.

Если ответ на все три вопроса выше "да, я хорошо", то вы можете сделать следующее:

  • создайте QueryBuilder для Animal, скажем animalQueryBuilder
  • создайте еще QueryBuilder для Breeder, скажем breederQueryBuilder
  • используйте animalQueryBuilder дляфильтр видов.
  • используйте breederQueryBuilder для фильтра местоположения
  • используйте один строитель или другой (это не имеет значения) для термина фильтр

Затем при создании запроса передайте и класс Animal, и класс Breeder методу createFullTextQuery.

Запрос должен возвращать как животных, так и заводчиков.

Что-то вроде этого:

QueryBuilder animalQueryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( Animal.class ).get();
QueryBuilder breederQueryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( Breeder.class ).get();

Query locationQuery = breederQueryBuilder.spatial()
    .onField( "breederLocation" )
    .within( 10.0, DistanceUnit.KM )
    .ofLatitude( 42.0 ).andLongitude( 42.0 )
    .createQuery();
Query speciesQuery = animalQueryBuilder.keyword()
    .onField( "species" )
    .matching( <some species> );
Query termsQuery = animalQueryBuilder.simpleQueryString()
    .onFields(
        "animalName", "breeder.company.legalName",
        "breeder.firstName", "breeder.lastName"
    )
    .withAndAsDefaultOperator()
    .matching( "Boston Terrier" );

Query booleanQuery = animalQueryBuilder.bool()
    .must( termsQuery )
    .must( animalQueryBuilder.bool()
        .should( locationQuery )
        .should( speciesQuery )
        .createQuery()
    )
    .createQuery();

FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery( booleanQuery, Animal.class, Breeder.class );
...