Hibernate Search JPA + Lucene 简单应用实例

一。假设现在有这么一个应用场景。数据库里存放了大量文章,我们想要通过输入关键字,从数据库中检索出相关的文章。

1.建立Article Entity:

public class Article {
	private String id;            //ID
	private String title;         //标题
	private String content;       //内容
        private String isPublication; //发布状态
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getIsPublication() {
		return isPublication;
	}
	public void setIsPublication(String isPublication) {
		this.isPublication = isPublication;
	}
}


2.建立索引:

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.Search;

public class IndexArticle {
	
	@PersistenceContext
	protected EntityManager entityManager;
	
	public void indexArticle(){
//		......具体编码不细写了
//		List<Article> articles = articleService.findList(null, null, null, first, count);
//		for (Article article : articless) {
//			index(article);
//		}
	}
	
	public void index(Article article){
		//Hibernate Search JPA
		FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
		fullTextEntityManager.index(articles);
	}
}


3.检索关键字:

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.Version;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.jpa.Search;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.dowik.dwshop.mall.entity.Article;

public class SearchArticle {
	
	@PersistenceContext
	protected EntityManager entityManager;

	public List<Article> searchResult(String keyword){
		
		try {
			
			//要搜索的关键词
			keyword = QueryParser.escape(keyword);
			
			//解析器,中文分词工具
			QueryParser titleParser = new QueryParser(Version.LUCENE_35, "title", new IKAnalyzer());
			titleParser.setDefaultOperator(QueryParser.AND_OPERATOR);
			Query titleQuery = titleParser.parse(keyword);
			
			//模糊搜索标题
			FuzzyQuery titleFuzzyQuery = new FuzzyQuery(new Term("title", keyword), 0.5F);
			
			//按词条搜索内容
			Query contentQuery = new TermQuery(new Term("content", keyword));
			
			//按词条搜索发布状态
			Query isPublicationQuery = new TermQuery(new Term("isPublication", "true"));
			
			//全文检索(标题搜索+内容搜索)
			BooleanQuery textQuery = new BooleanQuery();
			textQuery.add(titleQuery, Occur.SHOULD);
			textQuery.add(titleFuzzyQuery, Occur.SHOULD);
			textQuery.add(contentQuery, Occur.SHOULD);
			
			//发布状态+全文检索
			BooleanQuery query = new BooleanQuery();
			query.add(isPublicationQuery, Occur.MUST);
			query.add(textQuery, Occur.MUST);
			
			//Hibernate Search JPA
			FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
			FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, Articles.class);
			
			List<Article> resultList = fullTextQuery.getResultList();
			
			return resultList;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		return null;
	}
}


以上三个步骤构建了一个简单的 Hibernate Search JPA + Lucene 简单应用实例。



二。补充实例


import java.math.BigDecimal;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.Version;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.jpa.Search;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class ProductSearch {
    
    @PersistenceContext
    protected EntityManager entityManager;

    public List<ProductEntity> ProductInde(String inputKeyWord, BigDecimal startPrice, BigDecimal endPrice, String sortingType){
        
        //要搜索的关键词
        inputKeyWord = QueryParser.escape(inputKeyWord);
        
        try {
            //关键字检索
            Query keywordQuery = new QueryParser(Version.LUCENE_35, "keyword", new IKAnalyzer()).parse(inputKeyWord);
            
            //商品名称检索
            QueryParser nameParser = new QueryParser(Version.LUCENE_35, "name", new IKAnalyzer());
            nameParser.setDefaultOperator(QueryParser.AND_OPERATOR);
            Query nameQuery = nameParser.parse(inputKeyWord);
            
            //商品名称模糊检索
            FuzzyQuery nameFuzzyQuery = new FuzzyQuery(new Term("name", inputKeyWord), 0.5F);
        
            //商品简介检索
            TermQuery introductionQuery = new TermQuery(new Term("introduction", inputKeyWord));
            
            //是否上架
            TermQuery isMarketableQuery = new TermQuery(new Term("isMarketable", inputKeyWord));
            
            //是否是非售商品
            TermQuery isGiftQuery = new TermQuery(new Term("isGiftQuery", inputKeyWord));
        
            //全文检索(商品名称+商品简介)
            BooleanQuery textQuery = new BooleanQuery();
            textQuery.add(keywordQuery, Occur.SHOULD);
            textQuery.add(nameQuery, Occur.SHOULD);
            textQuery.add(nameFuzzyQuery, Occur.SHOULD);
            textQuery.add(introductionQuery, Occur.SHOULD);
            
            //发布状态+全文检索
            BooleanQuery query = new BooleanQuery();
            query.add(isMarketableQuery, Occur.MUST);
            query.add(isGiftQuery, Occur.MUST);
            query.add(textQuery, Occur.MUST);
            
            //价格范围检索
            if(startPrice!=null && endPrice!=null && startPrice.compareTo(endPrice)>0){
                BigDecimal temp = startPrice;
                startPrice = endPrice;
                endPrice = temp;
            } else if (startPrice!=null && endPrice!=null && startPrice.compareTo(new BigDecimal(0))>=0 && endPrice.compareTo(new BigDecimal(0))>=0) {
                NumericRangeQuery<Double> priceRangeQuery = NumericRangeQuery.newDoubleRange("price", startPrice.doubleValue(), endPrice.doubleValue(), true, true);
                query.add(priceRangeQuery, Occur.MUST);
            } else if(startPrice != null && startPrice.compareTo(new BigDecimal(0)) >= 0) {
                NumericRangeQuery<Double> priceRangeQuery = NumericRangeQuery.newDoubleRange("price", startPrice.doubleValue(), null, true, false);
                query.add(priceRangeQuery, Occur.MUST);
            } else if(endPrice != null && endPrice.compareTo(new BigDecimal(0)) >= 0) {
                NumericRangeQuery<Double> priceRangeQuery = NumericRangeQuery.newDoubleRange("price", null, endPrice.doubleValue(), false, true);
                query.add(priceRangeQuery, Occur.MUST);
            }
            
            //Hibernate Search JPA
            FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
            FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, ProductEntity.class);
            
            //检索排序
            SortField[] sortFields = null;
            if("priceAsc".equalsIgnoreCase(sortingType)){
                sortFields = new SortField[]{new SortField("price", SortField.DOUBLE, false), new SortField("create", SortField.LONG, true)};
            } else if("priceDesc".equalsIgnoreCase(sortingType)) {
                sortFields = new SortField[]{new SortField("price", SortField.DOUBLE, true), new SortField("createDate", SortField.LONG, true)};
            } else if("salesDesc".equalsIgnoreCase(sortingType)) {
                sortFields = new SortField[]{new SortField("sales", SortField.INT, true), new SortField("createDate", SortField.LONG, true)};
            } else if("dateDesc".equalsIgnoreCase(sortingType)) {
                sortFields = new SortField[]{new SortField("createDate", SortField.LONG, true)};
            } else {
                sortFields = new SortField[]{new SortField("isTop", SortField.STRING, true), new SortField(null, SortField.SCORE), new SortField("modifyDate", SortField.LONG, true)};
            }
            fullTextQuery.setSort(new Sort(sortFields));
            
            //获取返回结果集
            List<ProductEntity> resultList = fullTextQuery.getResultList();
            return resultList;
        
        } catch (ParseException e) {
            e.printStackTrace();
        }
        
        return null;
        
    }
}
补充例子更加贴合实际业务需求,通过输入关键字,从数据库中检索出相关的商品。


多了Lucene数值范围的检索NumericRangeQuery,和检索结果的排序SortField。

转载于:https://my.oschina.net/lock0818/blog/420574

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值