/**
*
*/
package com.ccp.lucene;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.annotation.Resource;
import jxl.write.DateTime;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Version;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.lucene.IKAnalyzer;
import com.aliyun.common.utils.DateUtil;
import com.ccp.ServiceFactory;
import com.ccp.core.entity.goods.Goods;
import com.ccp.util.CustomBeanFactory;
import com.ccp.util.PageBean;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.*;
/**
* @author Dylan Wang
*
* 09/05/2014
*
* this class is using for creating index or searching
*
*/
public class LuceneFactory {
private static String currentIndex;
// @Resource
// private ServiceFactory s;
@Resource
public ServiceFactory s;
public LuceneFactory()
{
}
try {
properties = PropertiesLoaderUtils
.loadAllProperties("luceneIndex.properties");
String indexA = properties.getProperty("LuceneIndexA");
String indexB = properties.getProperty("LuceneIndexB");
currentIndex = indexA;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void index(List<Goods> goods) throws IOException
{
System.out.println("开始创建索引文件……");
IKAnalyzer analyzer= new IKAnalyzer();
IndexWriterConfig indexWriterConfig= new IndexWriterConfig(Version.LUCENE_44,analyzer);
IndexWriter indexWriter = null;
try {
Directory directory = FSDirectory.open(new File(currentIndex));
//创建 IndexWriter
indexWriter= new IndexWriter(directory,indexWriterConfig);
System.out.println("开始创建索引文档信息……");
//创建索引文件
addDocument(indexWriter,goods);
System.out.println("索引文件创建完成!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("索引文件创建失败!");
}
finally
{
//优化索引并关闭Writer
if(indexWriter!=null)
indexWriter.close();
}
}
//创建索引文件,
private void addDocument(IndexWriter writer, List<Goods> goods) throws IOException {
for (Goods good : goods) {
Document document= new Document();
document.add(new Field("ID",good.getId().toString(),Field.Store.YES,Field.Index.NO));
document.add(new Field("title",good.getTitle(),Field.Store.YES,Field.Index.ANALYZED));
document.add(new Field("createTime",good.getId().toString(),Field.Store.YES,Field.Index.NO));
document.add(new Field("SalesNum", s.orderService.querySales(good.getId()).toString(), Field.Store.YES, Field.Index.NO));
document.add(new Field("PageViewNum", "100", Field.Store.YES, Field.Index.NO));
writer.addDocument(document);
}
}
/**
* 构造排序字段
* @param sortParm 排序字段 (1-createTime 2-SalesNum 3-PageViewNum)
* @return
*/
private String getSortField(int sortParm) {
String sortField="";
//构造排序字段
switch (sortParm) {
case 2:
sortField = "SalesNum";
break;
case 3:
sortField = "PageViewNum";
break;
case 1:
default:
sortField = "createTime";
break;
}
return sortField;
}
/**
* 获取排序方式,True-降序 False-升序
* @param sortType 排序方式 (1-升序 2-降序)
* @return
*/
private boolean getSortType(int sortType) {
boolean isDesc =true;
switch (sortType) {
case 1:
isDesc =false;
break;
case 2:
default:
isDesc=true;
break;
}
return isDesc;
}
/**
*
* @param keyWord 搜索关键字
* @param pageBean 分页数据
* @param sortParm 排序字段 (1-createTime 2-SalesNum 3-PageViewNum)
* @param sortType 排序方式 (1-升序 2-降序)
* @return
* @throws IOException
* @throws ParseException
* @throws InvalidTokenOffsetsException
*/
public List<Goods> search(String keyWord,PageBean pageBean,int sortParm,int sortType) throws IOException, ParseException, InvalidTokenOffsetsException {
String sortField = getSortField(sortParm);
boolean isDesc = getSortType(sortType);
List<Goods> goodsList= new ArrayList<Goods>();
File file = new File(currentIndex);
IndexReader reader = DirectoryReader.open(FSDirectory.open(file));
IndexSearcher searcher = new IndexSearcher(reader);
IKAnalyzer analyzer = new IKAnalyzer();
MultiFieldQueryParser fieldQueryParser = new MultiFieldQueryParser(Version.LUCENE_44, new String[]{"title"},analyzer);
Query query= fieldQueryParser.parse(keyWord);
TopDocs resultDocs = searcher.search(query, pageBean.getPageNumber() * pageBean.getPageSize(),new Sort(new SortField(sortField,SortField.Type.DOC ,isDesc)));
System.out.println("第一次查询总条数:" + resultDocs.totalHits);
System.out.println("第一次查询总条数:" + resultDocs.scoreDocs.length);
ScoreDoc scoreDoc = null;
//返回上页最后一条数据的编号
int lastPageDocNumber = (pageBean.getPageNumber() -1) * pageBean.getPageSize();
if(lastPageDocNumber>0)
{
scoreDoc = resultDocs.scoreDocs[lastPageDocNumber -1];
}
if(scoreDoc!=null)
System.out.println("上一页的最后一条为:"+ searcher.doc(scoreDoc.doc).get("ID"));
//查询结果集,并按照指定字段排序,排序按照文档排序,非积分
TopDocs topDocs= searcher.searchAfter(scoreDoc, query, pageBean.getPageSize(), new Sort(new SortField(sortField,SortField.Type.DOC ,isDesc)));
System.out.println("第二次查询总条数:" + topDocs.totalHits);
System.out.println("第二次查询总条数:" + topDocs.scoreDocs.length);
//设置总条数
pageBean.setTotalDatas(topDocs.totalHits);
//设置高亮
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
Goods goods;
for (ScoreDoc item : topDocs.scoreDocs) {
Document document = searcher.doc(item.doc);
goods = new Goods();
goods.setId(Integer.parseInt(document.get("ID")));
//高亮“Title”列
String title = document.get("title");
TokenStream tokenStream = analyzer.tokenStream("title", new StringReader(title));
goods.setTitle(highlighter.getBestFragment(tokenStream, title));
goods.setCreateTime(com.ccp.util.DateUtil.dateFormat(document.get("createTime")));
goods.setSalesNum(Integer.parseInt(document.get("SalesNum")));
goods.setPageViewNum(Integer.parseInt(document.get("PageViewNum")));
goodsList.add(goods);
}
return goodsList;
}
}
*
*/
package com.ccp.lucene;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.annotation.Resource;
import jxl.write.DateTime;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.Version;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.lucene.IKAnalyzer;
import com.aliyun.common.utils.DateUtil;
import com.ccp.ServiceFactory;
import com.ccp.core.entity.goods.Goods;
import com.ccp.util.CustomBeanFactory;
import com.ccp.util.PageBean;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.*;
/**
* @author Dylan Wang
*
* 09/05/2014
*
* this class is using for creating index or searching
*
*/
public class LuceneFactory {
private static String currentIndex;
// @Resource
// private ServiceFactory s;
@Resource
public ServiceFactory s;
public LuceneFactory()
{
}
public void init() {
Properties properties;try {
properties = PropertiesLoaderUtils
.loadAllProperties("luceneIndex.properties");
String indexA = properties.getProperty("LuceneIndexA");
String indexB = properties.getProperty("LuceneIndexB");
currentIndex = indexA;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void index(List<Goods> goods) throws IOException
{
System.out.println("开始创建索引文件……");
IKAnalyzer analyzer= new IKAnalyzer();
IndexWriterConfig indexWriterConfig= new IndexWriterConfig(Version.LUCENE_44,analyzer);
IndexWriter indexWriter = null;
try {
Directory directory = FSDirectory.open(new File(currentIndex));
//创建 IndexWriter
indexWriter= new IndexWriter(directory,indexWriterConfig);
System.out.println("开始创建索引文档信息……");
//创建索引文件
addDocument(indexWriter,goods);
System.out.println("索引文件创建完成!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("索引文件创建失败!");
}
finally
{
//优化索引并关闭Writer
if(indexWriter!=null)
indexWriter.close();
}
}
//创建索引文件,
private void addDocument(IndexWriter writer, List<Goods> goods) throws IOException {
for (Goods good : goods) {
Document document= new Document();
document.add(new Field("ID",good.getId().toString(),Field.Store.YES,Field.Index.NO));
document.add(new Field("title",good.getTitle(),Field.Store.YES,Field.Index.ANALYZED));
document.add(new Field("createTime",good.getId().toString(),Field.Store.YES,Field.Index.NO));
document.add(new Field("SalesNum", s.orderService.querySales(good.getId()).toString(), Field.Store.YES, Field.Index.NO));
document.add(new Field("PageViewNum", "100", Field.Store.YES, Field.Index.NO));
writer.addDocument(document);
}
}
/**
* 构造排序字段
* @param sortParm 排序字段 (1-createTime 2-SalesNum 3-PageViewNum)
* @return
*/
private String getSortField(int sortParm) {
String sortField="";
//构造排序字段
switch (sortParm) {
case 2:
sortField = "SalesNum";
break;
case 3:
sortField = "PageViewNum";
break;
case 1:
default:
sortField = "createTime";
break;
}
return sortField;
}
/**
* 获取排序方式,True-降序 False-升序
* @param sortType 排序方式 (1-升序 2-降序)
* @return
*/
private boolean getSortType(int sortType) {
boolean isDesc =true;
switch (sortType) {
case 1:
isDesc =false;
break;
case 2:
default:
isDesc=true;
break;
}
return isDesc;
}
/**
*
* @param keyWord 搜索关键字
* @param pageBean 分页数据
* @param sortParm 排序字段 (1-createTime 2-SalesNum 3-PageViewNum)
* @param sortType 排序方式 (1-升序 2-降序)
* @return
* @throws IOException
* @throws ParseException
* @throws InvalidTokenOffsetsException
*/
public List<Goods> search(String keyWord,PageBean pageBean,int sortParm,int sortType) throws IOException, ParseException, InvalidTokenOffsetsException {
String sortField = getSortField(sortParm);
boolean isDesc = getSortType(sortType);
List<Goods> goodsList= new ArrayList<Goods>();
File file = new File(currentIndex);
IndexReader reader = DirectoryReader.open(FSDirectory.open(file));
IndexSearcher searcher = new IndexSearcher(reader);
IKAnalyzer analyzer = new IKAnalyzer();
MultiFieldQueryParser fieldQueryParser = new MultiFieldQueryParser(Version.LUCENE_44, new String[]{"title"},analyzer);
Query query= fieldQueryParser.parse(keyWord);
TopDocs resultDocs = searcher.search(query, pageBean.getPageNumber() * pageBean.getPageSize(),new Sort(new SortField(sortField,SortField.Type.DOC ,isDesc)));
System.out.println("第一次查询总条数:" + resultDocs.totalHits);
System.out.println("第一次查询总条数:" + resultDocs.scoreDocs.length);
ScoreDoc scoreDoc = null;
//返回上页最后一条数据的编号
int lastPageDocNumber = (pageBean.getPageNumber() -1) * pageBean.getPageSize();
if(lastPageDocNumber>0)
{
scoreDoc = resultDocs.scoreDocs[lastPageDocNumber -1];
}
if(scoreDoc!=null)
System.out.println("上一页的最后一条为:"+ searcher.doc(scoreDoc.doc).get("ID"));
//查询结果集,并按照指定字段排序,排序按照文档排序,非积分
TopDocs topDocs= searcher.searchAfter(scoreDoc, query, pageBean.getPageSize(), new Sort(new SortField(sortField,SortField.Type.DOC ,isDesc)));
System.out.println("第二次查询总条数:" + topDocs.totalHits);
System.out.println("第二次查询总条数:" + topDocs.scoreDocs.length);
//设置总条数
pageBean.setTotalDatas(topDocs.totalHits);
//设置高亮
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
Goods goods;
for (ScoreDoc item : topDocs.scoreDocs) {
Document document = searcher.doc(item.doc);
goods = new Goods();
goods.setId(Integer.parseInt(document.get("ID")));
//高亮“Title”列
String title = document.get("title");
TokenStream tokenStream = analyzer.tokenStream("title", new StringReader(title));
goods.setTitle(highlighter.getBestFragment(tokenStream, title));
goods.setCreateTime(com.ccp.util.DateUtil.dateFormat(document.get("createTime")));
goods.setSalesNum(Integer.parseInt(document.get("SalesNum")));
goods.setPageViewNum(Integer.parseInt(document.get("PageViewNum")));
goodsList.add(goods);
}
return goodsList;
}
}