问题
I have implemented hibernate lucene search in my JSP project. I can search contact_name,contact_email(one To Many),etc.,as a result it will return the list of contacts which matching to the search keyword successfully. But My problem is i want to know in which field(columnn_name) the 'match found'. Is there any way to grab the matching field name along with result.
This is how i wrote the search query and getting result
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();
and my contact class looks like this
@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;
}
Thank You In Advance..
回答1:
Is there any way to grab the matching field name along with result.
There is no built-in way to do that in Hibernate Search, no. There might be a way to do it by diving deep into Lucene's internals, but I wouldn't recommend that unless you have very heavy performance requirements.
No, really, the easiest way to do this is to do it yourself. Instead of running a single query, run three:
- one with a filter on "title OR text"
- one with a filter only on the "firstName" field, and a filter on IDs to only consider the entities that matched the first query
- one with a filter only on the "emailDetails.email_id" field, and a filter on IDs to only consider the entities that matched the first query
Then the first query gives you the results, the second query gives you the list of entities that matched on the "firstName" field, and the third query gives you the list of entities that matched on the "emailDetails.email_id" field.
Related question: https://stackoverflow.com/a/47832433/6692043.
回答2:
One convoluted way to do that might be to use highlighting and look for the particular token highlighting the words in the highlighted result.
There is a good article here explaining how to do that: https://howtodoinjava.com/lucene/lucene-search-highlight-example/.
Not sure it's going to be better than what Yoann proposed though.
回答3:
you can parse the results of org.apache.lucene.search.Explanation with weight( that is returned when Projection is applied to query.
来源:https://stackoverflow.com/questions/48557668/hibernate-search-how-to-get-matching-field-names