📄 topicimpl.java
字号:
/*
* Created on 2007-5-27
* Last modified on 2007-6-10
* Powered by GamVan.com
*/
package com.yeqiangwei.club.service.search.impl;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import com.yeqiangwei.club.param.TopicParameter;
import com.yeqiangwei.club.service.ServiceLocator;
import com.yeqiangwei.club.service.ServiceWrapper;
import com.yeqiangwei.club.service.model.ContentModel;
import com.yeqiangwei.club.service.model.TopicModel;
import com.yeqiangwei.club.service.search.AnalyzerFactory;
import com.yeqiangwei.club.service.search.Constants;
import com.yeqiangwei.club.service.search.MultiFiledQuery;
import com.yeqiangwei.club.service.search.SearchParameter;
import com.yeqiangwei.club.service.search.SearchProvider;
import com.yeqiangwei.club.service.search.SearchUtils;
import com.yeqiangwei.club.service.topic.TopicService;
import com.yeqiangwei.club.service.util.BasicInfoService;
import com.yeqiangwei.io.File;
import com.yeqiangwei.util.StringHelper;
import com.yeqiangwei.util.TypeChange;
import com.yeqiangwei.util.Validator;
@SuppressWarnings("unchecked")
public class TopicImpl extends SearchProvider{
private static final Logger logger = Logger.getLogger(TopicImpl.class);
private static int CANSEARCH = 1;
private static String MINID_FILE = null;
private static String INDEXPATH_TOPIC = null;
private static String TEMPPATH_TOPIC = null;
static
{
INDEXPATH_TOPIC = getBasicService().findOnly().getIndexPath()+"topics";
TEMPPATH_TOPIC = Constants.INDEX_PATH+"topics"+File.separator;
MINID_FILE = Constants.INDEX_PATH+"topics.txt";
}
public static void main(String args[]){
com.yeqiangwei.club.dao.hibernate.ConnectionManager.init();
com.yeqiangwei.club.util.LanguageUtils.instance();
TopicImpl st = new TopicImpl();
st.createIndex(1);
System.out.println("Job over");
/*
List<TopicModel> list = st.results(1,30,"美女 喜欢");
for(int i=0; i<list.size(); i++){
TopicModel model = list.get(i);
System.out.println(model.getTitle());
System.out.println(model.getContentModel().getContent());
}*/
System.out.println("========================");
}
private TopicModel filter(TopicModel model){
com.yeqiangwei.club.dao.hibernate.ConnectionManager.beginTransaction();
/*
* 如果标题表topicId和内容表的不符则依据标题表topicId去查找内容
*
*/
int topicId = model.getTopicId();
ContentModel content = model.getContentModel();
if(Validator.isEmpty(content)){
model = this.getTopicService().findTopicAndContentById(topicId);
}else{
int ctopicId = content.getTopicId();
if(topicId!=ctopicId){
model = this.getTopicService().findTopicAndContentById(topicId);
if(this.getTopicService().findById(ctopicId)==null){ //找不到标题的内容
int c = this.getTopicService().getContentDAO().deleteByTopicId(ctopicId);
logger.info("删除找不到标题的内容 topicId="+ctopicId);
if(c>0){
logger.info("删除成功!");
}else{
logger.info("删除失败!");
}
}
}
}
com.yeqiangwei.club.dao.hibernate.ConnectionManager.commitTransaction();
return model;
}
private void addDocs(TopicModel model, IndexWriter writer) throws IOException
{
model = this.filter(model);
if(Validator.isEmpty(model)||Validator.isEmpty(model.getTitle())){
logger.warn("找不到帖子!");
}else{
/*
System.out.println(model.getTopicId()+":"+model.getContentModel().getTopicId());
System.out.println("======================================");
System.out.println("");
*/
Constants.TOPICID = model.getTopicId();
Document doc = new Document();
doc.add(SearchUtils.Text("topicId",model.getTopicId()));
doc.add(SearchUtils.Text("userId",model.getUserId()));
doc.add(SearchUtils.Text("userName",model.getUserName()));
doc.add(SearchUtils.Text("createDateTime",model.getCreateDateTime()));
doc.add(SearchUtils.Text("title",model.getTitle()));
doc.add(SearchUtils.Text("content",model.getContentModel().getContent()));
doc.add(SearchUtils.Text("forumId",model.getForumId()));
writer.addDocument(doc);
File.createFile(MINID_FILE,String.valueOf(model.getTopicId()),"gb2312",true);
}
}
public void createIndex(int auto) {
if(state==1){
logger.info("任务重复!");
return ;
}
state=1;
if(auto==1){ //自动判断是创建还是追加
int id = 0;
try {
String strId = File.readTxt(MINID_FILE,"gb2312");
logger.info("MINID_FILE: "+strId);
id = TypeChange.stringToInt(strId);
} catch (IOException e) {
logger.error(e.toString());
}
if(id>0){
createIndex(false,id);
}else{
createIndex(true,id);
}
}else{ //强制重新生成索引
try {
File.createFile(MINID_FILE,"0","gb2312",true);
createIndex(true,0);
} catch (IOException e) {
logger.error(e.toString());
}
}
state=2;
}
public void createIndex(boolean iscreate, int minId) {
try {
logger.info("索引创建开始!");
logger.debug(TEMPPATH_TOPIC);
int maxBufferedDocs = getBasicService().findOnly().getMaxBufferedDocs();
int mergeFactor = getBasicService().findOnly().getMergeFactor();
int maxFieldLength = getBasicService().findOnly().getMaxFieldLength();
logger.debug("maxBufferedDocs: "+maxBufferedDocs);
logger.debug("mergeFactor: "+mergeFactor);
logger.debug("maxFieldLength: "+maxFieldLength);
File.createFolder(TEMPPATH_TOPIC);
IndexWriter writer = SearchUtils.getIndexWriter(TEMPPATH_TOPIC, iscreate);
writer.setMaxBufferedDocs(maxBufferedDocs); // Defalut 10
writer.setMergeFactor(mergeFactor); // Defalut 10
writer.setMaxFieldLength(maxFieldLength);
int rows = 200;
TopicParameter param = new TopicParameter();
param.setIsDeleted(false);
param.setOrderBy(new Byte((byte) 4));
param.setRows(new Integer(rows));
param.setMinId(new Integer(minId));
logger.info("rows: "+rows);
logger.info("minId: "+minId);
long count = this.getTopicService().countByParameter(param);
int pages = (int) (count/rows+1);
logger.info("pages: "+pages);
outer:
for(int page=1; page<=pages; page++){
param.setPage(new Integer(page));
List<TopicModel> list = this.getTopicService().findByParameter(param);
List<ContentModel> clist = this.getTopicService().findContentByParameter(param);
if(!Validator.isEmpty(list)&&!Validator.isEmpty(clist)){
if(list.size()==clist.size()){
for(int i=0; i<list.size(); i++){
TopicModel model = list.get(i);
ContentModel cmodel = clist.get(i);
model.setContentModel(cmodel);
this.addDocs(model,writer);
if(Constants.STOP==1){
state = 0;
break outer;
}
}
}else{
logger.warn("==============================");
logger.warn("取出的文章标题数和文章内容不符");
logger.warn("文章数:"+list.size());
logger.warn("内容数:"+clist.size());
logger.warn("当前页:"+page);
logger.warn("==============================");
for(int i=0; i<list.size(); i++){
TopicModel model = list.get(i);
this.addDocs(model,writer);
if(Constants.STOP==1){
state = 0;
break outer;
}
}
}
}
if(Constants.STOP==1){
state = 0;
break outer;
}
}
writer.optimize();
writer.close();
if(Constants.STOP!=1){
logger.info("终止搜索服务!");
CANSEARCH = 0;
logger.info("删除目录旧索引!"+INDEXPATH_TOPIC);
File.deleteFolder(INDEXPATH_TOPIC);
logger.info("移动新索引到目录:"+INDEXPATH_TOPIC);
File.copyFolder(TEMPPATH_TOPIC,INDEXPATH_TOPIC);
logger.info("开启索引服务器!");
CANSEARCH = 1;
logger.info("索引创建完成,本次任务结束!");
state=2;
}else{
logger.info("索引创建任务被强迫终止,本次任务结束!");
}
} catch (IOException e) {
logger.error(e.toString());
}
}
public void deleteIndex(int id) {
CANSEARCH = 0;
SearchUtils.delete(id,"topicId",INDEXPATH_TOPIC);
SearchUtils.delete(id,"topicId",TEMPPATH_TOPIC);
CANSEARCH = 1;
}
public List<TopicModel> results(SearchParameter param) {
if(CANSEARCH==0){
return null;
}
super.totalrows = 0;
super.runtimed = 0;
long begin = System.currentTimeMillis();
List<TopicModel> list = null;
try {
List<String> fields = new ArrayList<String>();
List<BooleanClause.Occur> flags = new ArrayList<BooleanClause.Occur>();
List<Float> boosts = new ArrayList<Float>();
List<String> keys = new ArrayList<String>();
fields.add("title");
fields.add("content");
fields.add("userName");
boosts.add(new Float(0.9));
boosts.add(new Float(0.5));
boosts.add(new Float(0.1));
keys.add(param.getKeys());
keys.add(param.getKeys());
keys.add(param.getKeys());
Searcher searcher = new IndexSearcher(INDEXPATH_TOPIC);
list = new ArrayList<TopicModel>();
if(!Validator.isEmpty(param.getForumId())&¶m.getForumId().intValue()>0){
fields.add("forumId");
boosts.add(new Float(1));
keys.add(String.valueOf(param.getForumId()));
flags.add(Occur.MUST);
flags.add(Occur.SHOULD);
flags.add(Occur.SHOULD);
flags.add(Occur.MUST);
}else{
flags.add(Occur.SHOULD);
flags.add(Occur.SHOULD);
flags.add(Occur.SHOULD);
}
Query query = MultiFiledQuery.parse(keys, fields, flags, boosts, AnalyzerFactory.getAnalyzer());
Hits hits = searcher.search(query);
SimpleHTMLFormatter sf = new SimpleHTMLFormatter("<font class=\"red\">","</font>");
QueryScorer scorer = new QueryScorer(query);
Highlighter highlighter_title = new Highlighter(sf, scorer);
Fragmenter fragmenter = new SimpleFragmenter(100);
highlighter_title.setTextFragmenter(fragmenter);
Highlighter highlighter_content = new Highlighter(sf, scorer);
highlighter_content.setTextFragmenter(new SimpleFragmenter(5));
if(hits!=null){
super.totalrows = (hits.length());
int listrows = param.getRows().intValue(); //每页显示行数
int startrows = 0; //显示记录集的起始行
int maxrows = listrows; //当前页最大行数
/* 翻页滤错开始 */
if(listrows>totalrows){
listrows = totalrows;
}
if(param.getPage().intValue()>1){
startrows = (listrows * (param.getPage().intValue()-1));
maxrows = startrows + listrows;
}
if(maxrows > totalrows){
maxrows = totalrows;
}
for (int i = startrows; i < maxrows; i++) {
try {
Document doc = hits.doc(i);
String title = doc.get("title");
title = StringHelper.htmlEncoder(title);
TokenStream stream = AnalyzerFactory.getAnalyzer().tokenStream("title",new StringReader(title));
title = highlighter_title.getBestFragment(stream, title);
String content = doc.get("content");
content = StringHelper.htmlEncoder(content);
stream = AnalyzerFactory.getAnalyzer().tokenStream("content",new StringReader(content));
content = highlighter_content.getBestFragments(stream,content,50,"...");
content = com.yeqiangwei.util.StringHelper.ubbPattern(content,"\\[(.*?)\\](.*?)\\[/(.*?)\\]","$2","");
if(Validator.isEmpty(title)){
title = doc.get("title");
title = StringHelper.htmlEncoder(title);
}
if(Validator.isEmpty(content)){
content = StringHelper.substring(doc.get("content"),0,50,"");
content = StringHelper.htmlEncoder(content);
}/*else{
content = content.replaceAll("<br/>"," ");
if(content.length()>200){
content = StringHelper.substring(content,0,200,"")+"...";
}
}*/
content = content.replaceAll("<br/>","...");
content = content.replaceAll(" "," ");
StringHelper.ubbPattern(content,"(\\s+)"," ","");
TopicModel tmodel = new TopicModel();
tmodel.setTopicId(TypeChange.stringToInt(doc.get("topicId")));
tmodel.setTitle(title);
tmodel.setUserId(TypeChange.stringToInt(doc.get("userId")));
tmodel.setUserName(doc.get("userName"));
tmodel.setForumId(TypeChange.stringToInt(doc.get("forumId")));
ContentModel cmodel = new ContentModel();
cmodel.setContent(content);
tmodel.setContentModel(cmodel);
list.add(tmodel);
} catch (IOException e) {
logger.error(e.toString());
}
}
}
searcher.close();
} catch (IOException e) {
logger.error(e.toString());
} catch (ParseException e) {
logger.error(e.toString());
}
long end = System.currentTimeMillis();
super.runtimed = (end - begin);
return list;
}
public TopicService getTopicService() {
return ServiceWrapper.<TopicService>getSingletonInstance(ServiceLocator.TOPIC);
}
public static BasicInfoService getBasicService() {
return ServiceWrapper.<BasicInfoService>getSingletonInstance(ServiceLocator.BASICINFO);
}
public int getState() {
return state;
}
public long getRuntimed() {
return runtimed;
}
public int getTotalrows() {
return super.totalrows;
}
public void setTotalrows(int totalrows) {
super.totalrows = totalrows;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -