job建索引
public class SoftIndexJob{
private Log log = LogFactory.getLog(SoftIndexJob.class);
private String indexpath = SearchEngineCore.getIndexpath("VSOYOU_SOFT_INDEX_PATH"); //索引的路径
private String lastDate; //上次建立索引的时间
public void doUpdateIndexData(){
SoftService softService = ServiceFactory.getBean(SoftService.class);
String lastModify = softService.getSoftLastModify();
if(StringUtils.isNotBlank(lastDate) &&StringUtils.isNotBlank(lastModify) && lastModify.equals(lastDate)){
return;
}
lastDate = lastModify;
int rows = 20000,start=0;
String tmpIndexPath = indexpath + File.separator + "softTmp";// 临时索引路径
IndexWriter writer = null;
try {
FileUtil.deleteFile(tmpIndexPath);// 删除临时索引目录
writer = SearchEngineCore.getIndexWriter(tmpIndexPath);
if(null == writer) return;
System.out.println("索引SoftIndex更新start");
while (true) {
List<Soft> list = softService.findSoftIndexRes(start,rows);
if(null ==list || list.isEmpty()) break;
Document doc = null;
for (Soft soft : list) {
doc = new Document();
doc.add(new LongField("softId", soft.getSoftId(), Field.Store.YES));
doc.add(new LongField("releaseId", soft.getReleaseId(), Field.Store.YES));
doc.add(new TextField("softName", StringUtils.isNotBlank(soft.getSoftName())?soft.getSoftName():"", Field.Store.YES));
doc.add(new StringField("iconPath", StringUtils.isNotBlank(soft.getIconPath())?soft.getIconPath():"", Field.Store.YES));
doc.add(new IntField("stars", soft.getStars(), Field.Store.YES));
doc.add(new LongField("fileSize", soft.getFileSize(), Field.Store.YES));
doc.add(new StringField("releaseDate", soft.getReleaseDate(), Field.Store.YES));
doc.add(new StringField("versionName", StringUtils.isNotBlank(soft.getVersionName())? soft.getVersionName():"", Field.Store.YES));
doc.add(new IntField("totalDownloads", soft.getTotalDownloads(), Field.Store.YES));
doc.add(new TextField("runType", soft.getRunType()+"", Field.Store.YES));
doc.add(new IntField("totalComemntCount", soft.getTotalComemntCount(), Field.Store.YES));
doc.add(new IntField("freeUse", soft.isFreeUse() == true ?1 :0, Field.Store.YES));
doc.add(new IntField("freeDownload", soft.isFreeDownload()==true ? 1:0, Field.Store.YES));
doc.add(new IntField("softCurrency", soft.getSoftCurrency(), Field.Store.YES));
doc.add(new LongField("versionCode", soft.getVersionCode(), Field.Store.YES));
doc.add(new StringField("packageName", StringUtils.isNotBlank(soft.getPackageName())?soft.getPackageName() : "", Field.Store.YES));
writer.addDocument(doc);
}
start += rows;
}
} catch (Exception e) {
e.printStackTrace();
log.info(e.getMessage(),e);
}finally{
if(null !=writer){
try {
writer.forceMerge(1);
writer.commit();
writer.close();
Directory dir = SearchEngineCore.getWriteDirectory(tmpIndexPath);
if(null !=dir && IndexWriter.isLocked(dir))
IndexWriter.unlock(dir);
System.out.println("索引SoftIndex更新end");
} catch (IOException e) {
e.printStackTrace();
log.info(e.getMessage(),e);
}
}
String indexDir = indexpath + File.separator + "softIndex";
SearchEngineCore.updateIndex(tmpIndexPath, indexDir);
}
}
}
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
/**
* 查询和排序对象
*
*/
public class QuerySort {
public Query query;
public Sort sort;
public QuerySort(Query query, Sort sort) {
this.query = query;
this.sort = sort;
}
public QuerySort() {
}
}
public class SearchEngineCore {
protected static Log log = LogFactory.getLog(SearchEngineCore.class);
protected String indexpath = null; //索引的路径
private static Object lock_r= new Object();
private static Object lock_w=new Object();
public SearchEngineCore(){}
// 创建索引IndexWriter
public static IndexWriter getIndexWriter(String indexDir) throws IOException {
IndexWriter indexWriter = null;
try {
synchronized(lock_w){
Directory indexDirectory = getWriteDirectory(indexDir);
IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_43, new IKAnalyzer());
if(IndexWriter.isLocked(indexDirectory)){
IndexWriter.unlock(indexDirectory);
}
indexWriterConfig.setOpenMode(OpenMode.CREATE);
indexWriter = new IndexWriter(indexDirectory,indexWriterConfig);
}
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage(), e);
}
return indexWriter;
}
public static Directory getWriteDirectory(String indexDir) {
Directory indexDirectory = null;
try {
File indexFile = new File(indexDir);
if(!indexFile.exists()) {
indexFile.mkdir();
}
indexDirectory = FSDirectory.open(indexFile);
} catch (IOException e) {
e.printStackTrace();
log.error(e.getMessage(), e);
}
return indexDirectory;
}
public static IndexSearcher getIndexSearcher(String indexDir){
IndexSearcher indexSearcher = null;
try {
synchronized(lock_r){
File indexFile = new File(indexDir);
if(!indexFile.exists()) {
return null;
}
IndexReader reader = DirectoryReader.open(FSDirectory.open(indexFile));
indexSearcher = new IndexSearcher(reader);
}
} catch (IOException e) {
e.printStackTrace();
log.error(e.getMessage(), e);
}
return indexSearcher;
}
/**
* 更新索引
* @param srcDir
* 更新目录
* @param dstDir
* 被更新目录
*/
public static void updateIndex(String srcDir, String dstDir) {
File dstDirFile = new File(dstDir);
if (dstDirFile.exists()) {
String dstBakDir = dstDir + ".bak";
File dstBakDirFile = new File(dstBakDir);
if (dstBakDirFile.exists()) {
boolean flag = FileUtil.deleteFile(dstBakDirFile);
log.info("delete " + dstBakDir + "====" + flag);
}
IndexUtil.renameFile(dstDir, dstBakDir);
}
IndexUtil.renameFile(srcDir, dstDir);
}
public static String getIndexpath(String idxPath) {
String indexPath = Config.getProperty(idxPath);
return SearchEngineCore.class.getResource("/").toString().replaceAll("WEB-INF/classes", indexPath)
.replaceAll("\\\\", "/").replace("file:/", "").trim();
}
}
public class UserInfo implements Serializable{
private static final long serialVersionUID = -1341713350583127283L;
private Long userId;
private String headImg;
private String nickName;
@JSONField(serialize=false)
private String loginName;
private int sex=-1; //性别 0=男 1=女
private int checkinCount=0; //签到数
private int favoriteCount=0; //收藏数
public UserInfo(){}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getHeadImg() {
return headImg;
}
public void setHeadImg(String headImg) {
this.headImg = headImg;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public int getCheckinCount() {
return checkinCount;
}
public void setCheckinCount(int checkinCount) {
this.checkinCount = checkinCount;
}
public int getFavoriteCount() {
return favoriteCount;
}
public void setFavoriteCount(int favoriteCount) {
this.favoriteCount = favoriteCount;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
}
索引搜索:
public class SoftSearch extends BaseServiceImpl{
private static String indexpath = SearchEngineCore.getIndexpath("VSOYOU_SOFT_INDEX_PATH"); //索引的路径
private static IndexSearcher indexSearcher = null;
public static void main(String[] args) throws ParseException {
long startTime = System.currentTimeMillis();
String searchWord ="QQ欢乐斗地主";
searchWord = SearchUtil.wmlEncode(searchWord);
searchWord = SearchUtil.traditionalToSimple(searchWord).trim();// 繁体转简体
int page =1;
int pageSize = 100;
TopDocs topDocs = search(searchWord,page,pageSize);
System.out.println("总共命中数:"+topDocs.totalHits);
if(topDocs != null && topDocs.totalHits !=0){
ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 搜索返回的结果集合
//查询起始记录位置
int begin = (page - 1)*pageSize ;
//查询终止记录位置
int end = Math.min(begin + pageSize, scoreDocs.length);
SoftSearch search = new SoftSearch();
List<Soft> softs = search.addHits2List(scoreDocs,begin,end);
for (int i = 0; i < softs.size(); i++) {
System.out.println("i: \t "+softs.get(i).getSoftName());
}
}
System.out.println("检索完成用时:"+(System.currentTimeMillis()-startTime)+"毫秒");
}
private static TopDocs search(String searchWord,int page,int pageSize) throws ParseException {
String indexDir = indexpath + File.separator + "softIndex";
indexSearcher = SearchEngineCore.getIndexSearcher(indexDir);
if(null == indexSearcher) return null;
TopDocs topDocs = null;
try {
BooleanQuery allQuery = new BooleanQuery();
//根据搜索关键字进行查询
QueryParser parser = new QueryParser(Version.LUCENE_43,"softName",new IKAnalyzer());
Query query = parser.parse(searchWord);
allQuery.add(query, BooleanClause.Occur.MUST);
QuerySort keywordQuerySort = getKeywordQuerySort();
allQuery.add(keywordQuerySort.query,BooleanClause.Occur.MUST);
topDocs = indexSearcher.search(allQuery, page*pageSize, keywordQuerySort.sort);
} catch (IOException e) {
e.printStackTrace();
}
return topDocs;
}
private List<Soft> addHits2List(ScoreDoc[] scoreDocs,int begin,int end) {
List<Soft> softs = new ArrayList<Soft>();
try {
this.commentsInfoDao = ServiceFactory.getBean(CommentsInfoDao.class);
for (int i = begin; i < end; i++) {
int docID = scoreDocs[i].doc;
Soft soft = new Soft();
Document doc = indexSearcher.doc(docID);
if(StringUtils.isNotBlank(doc.get("fileSize")))
soft.setFileSize(Long.valueOf(doc.get("fileSize")));
if(StringUtils.isNotBlank(doc.get("freeDownload")))
soft.setFreeDownload(doc.get("freeDownload").equals("1"));
if(StringUtils.isNotBlank(doc.get("freeUse")))
soft.setFreeUse(doc.get("freeUse").equals("1"));
soft.setIconPath(doc.get("iconPath"));
soft.setReleaseDate(doc.get("releaseDate"));
soft.setReleaseId(Long.valueOf(doc.get("releaseId")));
soft.setSoftName(doc.get("softName"));
if(StringUtils.isNotBlank(doc.get("stars")))
soft.setStars(Integer.valueOf(doc.get("stars")));
int commentRowCount = NumberUtils.strToInt(commentsInfoDao.getSoftCommentRowCount(Long.valueOf(doc.get("releaseId"))));
if(commentRowCount >=0){
soft.setTotalComemntCount(commentRowCount);
}else if(StringUtils.isNotBlank(doc.get("totalComemntCount"))){
soft.setTotalComemntCount(Integer.valueOf(doc.get("totalComemntCount")));
}
if(StringUtils.isNotBlank(doc.get("totalDownloads")))
soft.setTotalDownloads(Integer.valueOf(doc.get("totalDownloads")));
soft.setVersionName(doc.get("versionName"));
if(StringUtils.isNotBlank(doc.get("softCurrency")))
soft.setSoftCurrency(Integer.valueOf(doc.get("softCurrency")));
if(StringUtils.isNotBlank(doc.get("versionCode")))
soft.setVersionCode(Long.valueOf(doc.get("versionCode")));
if(StringUtils.isNotBlank(doc.get("packageName")))
soft.setPackageName(doc.get("packageName"));
softs.add(soft);
}
} catch (IOException e) {
e.printStackTrace();
}
return softs;
}
private static QuerySort getKeywordQuerySort() {
QuerySort querySort = new QuerySort();
querySort.query = new TermQuery(new Term("runType", "100"));
querySort.sort = new Sort(new SortField[] {
new SortField("totalDownloads", SortField.Type.INT, true),
new SortField("totalComemntCount", SortField.Type.INT, true),
new SortField("releaseDate", SortField.Type.STRING, true),
new SortField("freeDownload", SortField.Type.INT, true)
});
return querySort;
}
public Map<String, Object> searchKeyWord(String searchWord,int page,int pageSize) {
Map<String, Object> map = new HashMap<String, Object>();
map.put(Const.IMG_DOMAIN_KEY,Const.IMG_DOMAIN_VALUE);
try {
searchWord = SearchUtil.wmlEncode(searchWord);
searchWord = SearchUtil.traditionalToSimple(searchWord).trim();// 繁体转简体
TopDocs topDocs = search(searchWord,page,pageSize);
if(topDocs == null || topDocs.totalHits ==0){
map.put("list", null);
return map;
}
map.put("pageCount", getPageCount(topDocs.totalHits,pageSize));
ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 搜索返回的结果集合
//查询起始记录位置
int begin = (page - 1)*pageSize ;
//查询终止记录位置
int end = Math.min(begin + pageSize, scoreDocs.length);
List<Soft> softs = addHits2List(scoreDocs,begin,end);
map.put("list", softs);
/*SoftSearchKeyWord searchKeyWord = new SoftSearchKeyWord();
searchKeyWord.setKeyword(searchWord);
Thread thread = new Thread(new SearchKeyWordThread(searchKeyWord));
thread.start();*/
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
private int getPageCount(int rowCount, int pageSize) {
int pageCount = 1;
if ((rowCount % pageSize) == 0) {
pageCount = rowCount / pageSize;
} else {
pageCount = rowCount / pageSize + 1;
}
if (pageCount == 0) {
pageCount = 1;
}
return pageCount;
}
}
需要jar包:
相关推荐
Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发并维护。在Java编程环境中,它为开发者提供了强大的文本检索功能,使得在海量数据中快速查找相关信息变得简单易行。本篇文章将详细探讨Lucene 4.3.1版本的...
Lucene是一个强大的全文检索库,广泛应用于搜索引擎和信息检索系统中。在中文处理方面,IKAnalyzer是一个优秀的开源中文分词器,专为Lucene设计,旨在提高中文分词的准确性和效率。本文将深入探讨IKAnalyzer的特性和...
Lucene 被广泛应用在各种搜索引擎项目中,如网站的站内搜索、企业内部文档检索系统、电子商务产品搜索等。同时,许多知名搜索引擎产品如 Elasticsearch、Solr 等都是基于 Lucene 构建的。 总之,Lucene 作为一款...
Lucene是Apache软件基金会的一个开源项目,它是一个高性能、全文本搜索库,提供了一个强大的信息检索引擎框架。这个压缩包“基于lucene 的简单搜索引擎.rar”很可能是为了演示如何利用Lucene来构建一个基本的搜索...
Apache Lucene 是一个开源的全文搜索引擎库,由Java编写,被广泛应用于各种信息检索系统中。4.10.3 版本是Lucene的一个稳定版本,它在前代的基础上进行了优化和改进,提供了更高效、更灵活的搜索功能。以下将详细...
Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发并维护,广泛应用于各种信息检索系统中。它主要使用Java语言编写,因此在Java开发环境中应用尤为广泛。本篇文章将深入探讨Lucene的核心原理、主要组件以及...
4.3 智能推荐:结合机器学习,Lucene可以构建智能推荐系统,根据用户搜索历史推荐相关内容。 总结,Lucene 7.2.0作为信息检索领域的佼佼者,其高效、灵活的特性使其在各种项目中大放异彩。掌握Lucene的使用,不仅能...
Java全文搜索引擎Lucene是一款开源的、高性能的文本分析和检索库,它为开发者提供了在Java应用程序中实现全文搜索功能的能力。本篇将深入探讨Lucene 3.0.0版本的核心特性、设计理念以及使用方法。 一、Lucene概述 ...
总结,Lucene 5.3.1不仅是一个强大的全文检索工具,其源代码更是理解搜索引擎工作原理和优化技巧的宝贵资源。通过深入研究,开发者能够创建出更加高效、个性化的全文检索系统,满足各种应用场景的需求。
Lucene,作为Apache软件基金会下的一个开源全文检索库,为Java开发者提供了强大的文本搜索功能。其核心功能包括文档的索引、搜索以及相关性排序。Lucene 4.3.0是该库的一个重要版本,它在前代的基础上进行了多项优化...
Solr4.3是Apache Solr的一个早期版本,它是一个基于Lucene的全文搜索服务器,提供了高可配置、可扩展的搜索和分析功能。Solr4.3源代码的获取通常是为了深入理解其内部工作原理,进行定制开发或优化。在你提供的信息...
### 基于Lucene的语段模糊匹配中文检索系统设计与实现 #### 一、引言 随着信息技术的发展,信息检索技术在图书馆等领域的应用变得越来越重要。然而,在实际应用过程中,用户经常面临的问题是:能够记住文章或书籍...
15 4.2.3 中文切分词机制 17 4.3 Lucene与Spider的结合 18 4.4小节 21 第五章 基于Tomcat的Web服务器 22 5.1什么是基于Tomcat的Web服务器 22 5.2用户接口设计 22 5.3.1客户端设计 22 5.3.2...
- **Lucene优化查询分析**:特别设计的IKQueryParser,结合歧义分析算法,极大提升了基于Lucene的全文检索系统的命中率,改善了用户体验。 #### 3. 分词效果示例 IKAnalyzer在不同类型的文本中展现出强大的分词...
- Lucene是一种高性能的全文检索引擎,支持复杂的查询语法。 - 索引结构包括倒排索引等,能够高效地处理大量文本数据。 - **2.2.3 Lucene全文检索引擎** - Lucene是Apache基金会的一个开源项目,提供了强大的...
2> 全文检索的实现机制 【1】lucene学习笔记的目录如下 1. 概述 3 2. lucene 的包结构 3 3. 索引文件格式 3 4. lucene中主要的类 4 4.1. Document文档类 4 4.1.1. 常用方法 4 4.1.2. 示例 4 4.2. Field字段类 4 ...
Hibernate Search是Java领域中一个强大的全文搜索引擎,它将Apache Lucene的功能与Hibernate ORM框架相结合,为Java应用程序提供了便捷的、高性能的全文检索功能。在本文中,我们将深入探讨Hibernate Search 4.3.0...
##### 4.3 词典检索 词典检索实际上是在字典树中进行的查找操作,其原理非常直观:沿着树的路径匹配字符即可。然而,在IKAnalyzer中,词典检索与分词过程紧密耦合在一起,使得实现相对复杂。 #### 五、分词算法 ...