net.groupbuy.service.impl.SearchServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for net.groupbuy.service.impl.SearchServiceImpl.java

Source

/*
 * Copyright 2005-2013 shopxx.net. All rights reserved.
 * Support: http://www.shopxx.net
 * License: http://www.shopxx.net/license
 */
package net.groupbuy.service.impl;

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

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import net.groupbuy.Page;
import net.groupbuy.Pageable;
import net.groupbuy.dao.ArticleDao;
import net.groupbuy.dao.ProductDao;
import net.groupbuy.entity.Article;
import net.groupbuy.entity.Product;
import net.groupbuy.entity.Product.OrderType;
import net.groupbuy.service.SearchService;

import org.apache.commons.lang.StringUtils;
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.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.wltea.analyzer.lucene.IKAnalyzer;

/**
 * Service - ?
 * 
 * @author SHOP++ Team
 * @version 3.0
 */
@Service("searchServiceImpl")
@Transactional
public class SearchServiceImpl implements SearchService {

    /** ? */
    private static final float FUZZY_QUERY_MINIMUM_SIMILARITY = 0.5F;

    @PersistenceContext
    protected EntityManager entityManager;
    @Resource(name = "articleDaoImpl")
    private ArticleDao articleDao;
    @Resource(name = "productDaoImpl")
    private ProductDao productDao;

    public void index() {
        index(Article.class);
        index(Product.class);
    }

    public void index(Class<?> type) {
        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
        if (type == Article.class) {
            for (int i = 0; i < articleDao.count(); i += 20) {
                List<Article> articles = articleDao.findList(i, 20, null, null);
                for (Article article : articles) {
                    fullTextEntityManager.index(article);
                }
                fullTextEntityManager.flushToIndexes();
                fullTextEntityManager.clear();
                articleDao.clear();
            }
        } else if (type == Product.class) {
            for (int i = 0; i < productDao.count(); i += 20) {
                List<Product> products = productDao.findList(i, 20, null, null);
                for (Product product : products) {
                    fullTextEntityManager.index(product);
                }
                fullTextEntityManager.flushToIndexes();
                fullTextEntityManager.clear();
                productDao.clear();
            }
        }
    }

    public void index(Article article) {
        if (article != null) {
            FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
            fullTextEntityManager.index(article);
        }
    }

    public void index(Product product) {
        if (product != null) {
            FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
            fullTextEntityManager.index(product);
        }
    }

    public void purge() {
        purge(Article.class);
        purge(Product.class);
    }

    public void purge(Class<?> type) {
        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
        if (type == Article.class) {
            fullTextEntityManager.purgeAll(Article.class);
        } else if (type == Product.class) {
            fullTextEntityManager.purgeAll(Product.class);
        }
    }

    public void purge(Article article) {
        if (article != null) {
            FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
            fullTextEntityManager.purge(Article.class, article.getId());
        }
    }

    public void purge(Product product) {
        if (product != null) {
            FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
            fullTextEntityManager.purge(Product.class, product.getId());
        }
    }

    @SuppressWarnings("unchecked")
    @Transactional(readOnly = true)
    public Page<Article> search(String keyword, Pageable pageable) {
        if (StringUtils.isEmpty(keyword)) {
            return new Page<Article>();
        }
        if (pageable == null) {
            pageable = new Pageable();
        }
        try {
            String text = QueryParser.escape(keyword);
            QueryParser titleParser = new QueryParser(Version.LUCENE_35, "title", new IKAnalyzer());
            titleParser.setDefaultOperator(QueryParser.AND_OPERATOR);
            Query titleQuery = titleParser.parse(text);
            FuzzyQuery titleFuzzyQuery = new FuzzyQuery(new Term("title", text), FUZZY_QUERY_MINIMUM_SIMILARITY);
            Query contentQuery = new TermQuery(new Term("content", text));
            Query isPublicationQuery = new TermQuery(new Term("isPublication", "true"));
            BooleanQuery textQuery = new BooleanQuery();
            BooleanQuery query = new BooleanQuery();
            textQuery.add(titleQuery, Occur.SHOULD);
            textQuery.add(titleFuzzyQuery, Occur.SHOULD);
            textQuery.add(contentQuery, Occur.SHOULD);
            query.add(isPublicationQuery, Occur.MUST);
            query.add(textQuery, Occur.MUST);
            FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
            FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, Article.class);
            fullTextQuery.setSort(new Sort(new SortField[] { new SortField("isTop", SortField.STRING, true),
                    new SortField(null, SortField.SCORE), new SortField("createDate", SortField.LONG, true) }));
            fullTextQuery.setFirstResult((pageable.getPageNumber() - 1) * pageable.getPageSize());
            fullTextQuery.setMaxResults(pageable.getPageSize());
            return new Page<Article>(fullTextQuery.getResultList(), fullTextQuery.getResultSize(), pageable);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return new Page<Article>();
    }

    @SuppressWarnings("unchecked")
    @Transactional(readOnly = true)
    public Page<Product> search(String keyword, BigDecimal startPrice, BigDecimal endPrice, OrderType orderType,
            Pageable pageable) {
        if (StringUtils.isEmpty(keyword)) {
            return new Page<Product>();
        }
        if (pageable == null) {
            pageable = new Pageable();
        }
        try {
            String text = QueryParser.escape(keyword);
            TermQuery snQuery = new TermQuery(new Term("sn", text));
            Query keywordQuery = new QueryParser(Version.LUCENE_35, "keyword", new IKAnalyzer()).parse(text);
            QueryParser nameParser = new QueryParser(Version.LUCENE_35, "name", new IKAnalyzer());
            nameParser.setDefaultOperator(QueryParser.AND_OPERATOR);
            Query nameQuery = nameParser.parse(text);
            FuzzyQuery nameFuzzyQuery = new FuzzyQuery(new Term("name", text), FUZZY_QUERY_MINIMUM_SIMILARITY);
            TermQuery introductionQuery = new TermQuery(new Term("introduction", text));
            TermQuery isMarketableQuery = new TermQuery(new Term("isMarketable", "true"));
            TermQuery isListQuery = new TermQuery(new Term("isList", "true"));
            TermQuery isGiftQuery = new TermQuery(new Term("isGift", "false"));
            BooleanQuery textQuery = new BooleanQuery();
            BooleanQuery query = new BooleanQuery();
            textQuery.add(snQuery, Occur.SHOULD);
            textQuery.add(keywordQuery, Occur.SHOULD);
            textQuery.add(nameQuery, Occur.SHOULD);
            textQuery.add(nameFuzzyQuery, Occur.SHOULD);
            textQuery.add(introductionQuery, Occur.SHOULD);
            query.add(isMarketableQuery, Occur.MUST);
            query.add(isListQuery, 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;
            }
            if (startPrice != null && startPrice.compareTo(new BigDecimal(0)) >= 0 && endPrice != null
                    && endPrice.compareTo(new BigDecimal(0)) >= 0) {
                NumericRangeQuery<Double> numericRangeQuery = NumericRangeQuery.newDoubleRange("price",
                        startPrice.doubleValue(), endPrice.doubleValue(), true, true);
                query.add(numericRangeQuery, Occur.MUST);
            } else if (startPrice != null && startPrice.compareTo(new BigDecimal(0)) >= 0) {
                NumericRangeQuery<Double> numericRangeQuery = NumericRangeQuery.newDoubleRange("price",
                        startPrice.doubleValue(), null, true, false);
                query.add(numericRangeQuery, Occur.MUST);
            } else if (endPrice != null && endPrice.compareTo(new BigDecimal(0)) >= 0) {
                NumericRangeQuery<Double> numericRangeQuery = NumericRangeQuery.newDoubleRange("price", null,
                        endPrice.doubleValue(), false, true);
                query.add(numericRangeQuery, Occur.MUST);
            }
            FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
            FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(query, Product.class);
            SortField[] sortFields = null;
            if (orderType == OrderType.priceAsc) {
                sortFields = new SortField[] { new SortField("price", SortField.DOUBLE, false),
                        new SortField("createDate", SortField.LONG, true) };
            } else if (orderType == OrderType.priceDesc) {
                sortFields = new SortField[] { new SortField("price", SortField.DOUBLE, true),
                        new SortField("createDate", SortField.LONG, true) };
            } else if (orderType == OrderType.salesDesc) {
                sortFields = new SortField[] { new SortField("sales", SortField.INT, true),
                        new SortField("createDate", SortField.LONG, true) };
            } else if (orderType == OrderType.scoreDesc) {
                sortFields = new SortField[] { new SortField("score", SortField.INT, true),
                        new SortField("createDate", SortField.LONG, true) };
            } else if (orderType == OrderType.dateDesc) {
                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));
            fullTextQuery.setFirstResult((pageable.getPageNumber() - 1) * pageable.getPageSize());
            fullTextQuery.setMaxResults(pageable.getPageSize());
            return new Page<Product>(fullTextQuery.getResultList(), fullTextQuery.getResultSize(), pageable);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new Page<Product>();
    }

}