Hibernate Search- Как получить совпадающие имена полей
Я реализовал поиск lucene hibernate в моем проекте JSP. Я могу искать contact_name,contact_email(один To Many) и т. Д., В результате он вернет список контактов, которые успешно соответствуют поисковому слову. Но моя проблема в том, что я хочу знать, в каком поле (columnn_name) найдено совпадение. Есть ли способ получить соответствующее имя поля вместе с результатом.
Вот так я написал поисковый запрос и получил результат
List<Contact> searchResultContact = new ArrayList<Contact>();
FullTextSession fullTextSession = Search.getFullTextSession(session);
QueryBuilder qb = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Contact.class).get();
org.apache.lucene.search.Query query1 = qb.phrase().withSlop(2)
.onField("firstName")
.andField("emailDetails.email_id")
.boostedTo(5)
.sentence(searchText.toLowerCase()).createQuery();
org.apache.lucene.search.Query query2 = qb.keyword()
.onField("status")
.matching("0")
.createQuery();
org.apache.lucene.search.Query query = qb
.bool()
.must( query1 )
.must( query2)
.createQuery();
org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(query, Contact.class);
searchResultContact = hibQuery.list();
и мой класс контактов выглядит так
@Entity
@Indexed
@Table(name = "contact")
public class Contact {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "firstName", nullable = false, length = 128)
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO, analyzer = @Analyzer(definition = "ngram"))
private String firstName;
@OneToMany(fetch = FetchType.EAGER)
@Fetch(FetchMode.SELECT)
@JoinColumn(name = "contact_id")
@IndexedEmbedded
List<EmailDetails> emailDetails;
}
Заранее спасибо..
2 ответа
Есть ли способ получить соответствующее имя поля вместе с результатом.
Нет встроенного способа сделать это в Hibernate Search, нет. Возможно, есть способ сделать это, углубившись во внутренности Lucene, но я бы не советовал этого делать, если у вас очень высокие требования к производительности.
Нет, действительно, самый простой способ сделать это - сделать это самостоятельно. Вместо того, чтобы выполнять один запрос, запустите три:
- один с фильтром "заголовок или текст"
- один с фильтром только в поле "firstName" и фильтром по идентификаторам, чтобы рассматривать только объекты, соответствующие первому запросу
- один с фильтром только в поле "emailDetails.email_id" и фильтром по идентификаторам, который учитывает только объекты, соответствующие первому запросу
Затем первый запрос выдает результаты, второй запрос выдает список сущностей, которые совпадают в поле "firstName", а третий запрос выдает список сущностей, которые соответствуют в поле "emailDetails.email_id".
Связанный вопрос: /questions/19312409/est-li-sposob-v-hibernate-search-dlya-faseta-po-polyam-v-kotoryih-byil-najden-poiskovyij-termin/19312423#19312423.
Одним из сложных способов сделать это может быть использование выделения и поиск конкретного токена, выделяющего слова в выделенном результате.
Здесь есть хорошая статья, объясняющая, как это сделать: https://howtodoinjava.com/lucene/lucene-search-highlight-example/.
Не уверен, что это будет лучше, чем то, что предложил Йоанн.
Вы можете проанализировать результаты org.apache.lucene.search.Explanation с помощью веса (который возвращается, когда проекция применяется к запросу.