How can I search for two terms in Hibernate Search and get them both in result?

放肆的年华 提交于 2019-12-08 06:53:01

问题


Is there some way to find results in Hibernate Search with all searched terms ? What I mean is that, for instance, I search for a given term like "house" and I got a list of "Houses". However, if I'd want go refine my search and look for "house" and "pool", I'd like to get a list of "house" AND "pool" and not a list of "house" OR "pool". I'm not sure I'm clear enough. So, basically, what I need is to perform a search with more than one word and the search must consider them all, not only one. Is that possible? Thanks


回答1:


you can set default operator to AND using QueryParser:

QueryParser queryParser = new QueryParser(Version.LUCENE_36, "yourfield",standardAnalyzer);     
// query terms should ANDed by default
queryParser.setDefaultOperator(Operator.AND);
Query luceneQuery = queryParser.parse("house pool");
// turn it into an hibernate search query
org.hibernate.search.FullTextQuery hibQuery =
session.createFullTextQuery(luceneQuery, YourClass.class);



回答2:


Maybe this is what you want,Assuming you have an String array of terms to be searched.

BooleanQuery finalLuceneQuery=new BooleanQuery();
for(String term:terms)
{
  TermQuery query = new TermQuery(new Term("your search field", term));

  finalLuceneQuery.add(query,BooleanClause.Occur.MUST);
}

FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(finalLuceneQuery, <your class>.class);

Cheers.




回答3:


When searching on several fields it is possible to specify terms that MUST, SHOULD or MUST_NOT appear in each field. The following code is based on Lucene 4.10.3.

// fields we are interested in
String[] fields = {"description", "content"};
// terms SHOULD appear in description OR MUST appear in content
BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD, BooleanClause.Occur.MUST};
// besides the StandardAnalyzer there are analysers for many languages like
// FrenchAnalyser, RussianAnalyser and so on
Analyzer analyzer = new StandardAnalyzer();
// create a multi field query using parse static method
org.apache.lucene.search.Query luceneQuery = 
    MultiFieldQueryParser.parse("house pool", fields, flags, analyzer);
// convert to Hibernate query
org.hibernate.search.FullTextQuery hibQuery =
    session.createFullTextQuery(luceneQuery, YourClass.class);

If using JPA you will need to convert it to a JPA query:

// get an EntityManager from your EntityManagerFactory (emf)
javax.persistence.EntityManager em = emf.createEntityManager();
// Convert it to a FullTextEntityManager
org.hibernate.search.jpa.FullTextEntityManager ftem =
    org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
// convert it to a JPA query
javax.persistence.Query jpaQuery =
    ftem.createFullTextQuery(luceneQuery, YourClass.class);

Yet another way of getting the Lucene query (maybe simpler?):

// fields we are interested in
String[] fields = {"description", "content"};
// besides the StandardAnalyzer there are analysers for many languages like
// FrenchAnalyser, RussianAnalyser and so on
Analyzer analyzer = new StandardAnalyzer();
// to set MUST for all fields we need an instance of the parser
MultiFieldQueryParser mfqp = new MultiFieldQueryParser(fields, analyzer);
mfqp.setDefaultOperator(QueryParser.Operator.AND);
org.apache.lucene.search.Query luceneQuery = mfqp.parse("house pool");



回答4:


There is no need of using any Analyzer here coz Hibernate implicitly uses StandardAnalyzer which will split the words based on white spaces so the solution here is set the Analyze to NO on the field it will automatically performs Multi Phrase Search

@Column(name="skill")
@Field(index=Index.YES, analyze=Analyze.NO, store=Store.NO)
@Analyzer(definition="SkillsAnalyzer")
private String skill;



回答5:


Use the key word MUST during query building. Hibernate Search also supports combining queries using various strategies:

-SHOULD: the query should contain the matching elements of the subquery

-MUST: the query must contain the matching elements of the subquery

-MUST NOT: the query must not contain the matching elements of the subquery

The aggregations are similar to the boolean ones AND, OR and NOT.

    Query combinedQuery = queryBuilder
   .bool()

   .must(queryBuilder.phrase()
   .onField("productName).sentence("samsung galaxy s8")
   .createQuery())

   .must(queryBuilder.keyword()
   .onField("productCategory").matching("smartphone")
   .createQuery())

   .createQuery();


    // wrap Lucene query in an Hibernate Query object
    org.hibernate.search.jpa.FullTextQuery jpaQuery =
    fullTextEntityManager.createFullTextQuery(combinedQuery, Product.class);

    // execute search and return results (sorted by relevance as default)
    @SuppressWarnings("unchecked")
    List<Product> results = jpaQuery.getResultList();

This reference is obtained from the link http://www.baeldung.com/hibernate-search



来源:https://stackoverflow.com/questions/18422512/how-can-i-search-for-two-terms-in-hibernate-search-and-get-them-both-in-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!