Hibernate поиск по двум объектам без встроенного индекса - PullRequest
0 голосов
/ 12 февраля 2020

Я пытаюсь использовать Hibernate Search 6 и elasti c search. Простой пример того, что я пытаюсь построить, выглядит следующим образом.

У меня есть Book сущность, которая имеет такую ​​информацию, как title, authorName, genre, price
У меня есть Shop объект, который имеет такую ​​информацию, как shopName, phone, email, location
У меня есть " объединяющий стол ", который делает много-много сопоставлений между закоулками и магазинами. (Книга может быть во многих магазинах, а в магазине может быть много книг)

Я пытаюсь выполнить поиск по названию и местоположению, в идеале, чтобы найти книгу в месте, ближайшем к входу. Стандартный пример автора книги в документации требует аннотации IndexedEmbedded, что в моем случае не представляется возможным, поскольку я использую соединительную таблицу. Есть ли альтернативный подход к решению этой проблемы

1 Ответ

0 голосов
/ 14 февраля 2020

Мои сущности

    @Indexed
    public class Book extends PanacheEntity{
      public String title;
      public String authorName;  
    @OneToMany(mappedBy = "book", fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE })
      public List<BookShopRelation> bookShopRelation = new ArrayList<>();
    }  


    @Indexed
    public class Shop extends PanacheEntity{
      public String name;
      public String city;  
      @OneToMany(mappedBy = "shop", fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE })
      private List<BookShopRelation> bookShopRelation = new ArrayList<>();
    }

    @Indexed
    public class BookShopRelation extends PanacheEntity{
    @JoinColumn(name = "shop_id")
        @ManyToOne(fetch = FetchType.EAGER, optional = false)
        @IndexedEmbedded
        private Shop shop;

        @JoinColumn(name = "offer_id")
        @ManyToOne(fetch = FetchType.EAGER, optional = false)
        @IndexedEmbedded
        private Book book;
    }   

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

 List<BookShopRelation> result = Search.session(entityManager)
                .search(BookShopRelation.class) .predicate(f ->
                        pattern == null || pattern.trim().isEmpty() ?
                                f.matchAll() : 
                                f.simpleQueryString()
                                    .fields("book.title").matching(pattern) 
                    ) 
                    .fetchHits(size.orElse(20));
...