Усиление поиска Hibernate со значениями из другой таблицы

Я использую поиск в спящем режиме (последняя версия) с локальным сервером Lucene. У меня есть две следующие сущности;

@Entity
@Indexed
public class A {

    @Id
    private Long id; 

    @FullTextField
    private String text;

    @KeywordField
    private String keyword;
}

@Entity
public class B {
    
    private BigDecimal number;

    @OneToOne
    @JoinColumn(name = "a_id")
    private A a;
}

У меня есть массовый индексатор, который обрабатывает индексирование сущностей A при запуске приложения. При поиске я хочу, чтобы результаты поиска были упорядочены по полю number объекта B.

Моя функция поиска - это простой логический предикат, который выглядит следующим образом

.where(f -> f.bool()
          .should(f.match().field("text").matching(query))
          .should(f.match().field("keyword").matching(query.toUpperCase(Locale.ENGLISH)))
)
.fetch(offset, limit)

Что мне делать, чтобы упорядочить / ускорить результаты поиска в зависимости от другого поля другого объекта, которое имеет однозначное отношение?


person Samed Bicer    schedule 03.03.2021    source источник


Ответы (1)


Вы используете слово boost, но я думаю, вы просто после сортировки. Загрузочная загрузка - это другая концепция, которая влияет на оценку и только косвенно влияет на порядок совпадений.

Чтобы отсортировать по этому свойству number, вам нужно будет встроить его в индексный документ, созданный для A. Для этого используйте @IndexedEmbedded < / а>:

@Entity
@Indexed
public class A {

    @Id
    private Long id; 

    @FullTextField
    private String text;

    @KeywordField
    private String keyword;

    // Add this, and make sure to update it every time you update B.a
    @OneToOne(mappedBy = "a")
    @IndexedEmbedded
    private B b;
}

@Entity
public class B {
    
    private BigDecimal number;

    @OneToOne
    @JoinColumn(name = "a_id")
    private A a;
}

ПРЕДУПРЕЖДЕНИЕ. Убедитесь, что каждый раз, когда вы вызываете b.setA(...), вы также вызываете a.setB(...), чтобы все объекты были согласованы. В противном случае Hibernate Search не сможет правильно проиндексировать ваши данные.

Затем аннотируйте number, чтобы он был проиндексирован и сортируемый:

@Entity
public class B {
    
    @GenericField(searchable = Searchable.NO, sortable = Sortable.YES)
    private BigDecimal number;

    @OneToOne
    @JoinColumn(name = "a_id")
    private A a;
}

Затем добавьте sort на ваш запрос:

.where(f -> f.bool()
          .should(f.match().field("text").matching(query))
          .should(f.match().field("keyword").matching(query.toUpperCase(Locale.ENGLISH)))
)
.sort(f -> f.field("b.number").asc())
.fetch(offset, limit)
person yrodiere    schedule 04.03.2021