📄 userimpl.java
字号:
/*
* Created on 2007-9-19
* Last modified on 2007-9-26
* Powered by YeQiangWei.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.search.BooleanClause;
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.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.exception.ClubException;
import com.yeqiangwei.club.ip.IPSeeker;
import com.yeqiangwei.club.param.UserParameter;
import com.yeqiangwei.club.service.ServiceLocator;
import com.yeqiangwei.club.service.ServiceWrapper;
import com.yeqiangwei.club.service.model.UserModel;
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.user.UserIndexedService;
import com.yeqiangwei.club.service.user.UserService;
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;
public class UserImpl extends SearchProvider<UserModel>{
private static final Logger logger = Logger.getLogger(UserImpl.class);
private static int CANSEARCH = 1; //索引是否可用
private static String MINID_FILE = null;
private static String INDEXPATH_USER = null;
private static String TEMPPATH_USER = null;
static
{
if(INDEXPATH_USER==null)INDEXPATH_USER = getBasicService().findOnly().getIndexPath()+"users";
if(TEMPPATH_USER==null)TEMPPATH_USER = Constants.INDEX_PATH+"users"+File.separator;
if(MINID_FILE==null)MINID_FILE = Constants.INDEX_PATH+"users.txt";
}
public static void main(String args[]) {
List<String> list = IPSeeker.getInstance().IPParser("192.76.71.99");
if(!Validator.isEmpty(list)){
for(int i=0; i<list.size(); i++){
System.out.println(list.get(i));
}
}
}
private void addDocs(UserModel userModel, IndexWriter writer) throws IOException, ClubException
{
if(Validator.isEmpty(userModel)){
return ;
}
/*
* 这个用可能已经在这台服务器上被索引过了
*/
this.getUserIndexedService().create(userModel.getUserId());
logger.debug("已在当前服务器上被索引!");
if(!userModel.getIsIndexed()){ //如果没索引后修改过则先删除原来的索引
this.deleteIndex(userModel.getUserId());
}
Document doc = new Document();
doc.add(SearchUtils.Text("userId",userModel.getUserId()));
doc.add(SearchUtils.Text("userName",userModel.getUserName()));
doc.add(SearchUtils.Text("penName",userModel.getPenName()));
doc.add(SearchUtils.Text("sex",userModel.getSex()));
doc.add(SearchUtils.Text("emailAddress",userModel.getEmailAddress()));
doc.add(SearchUtils.Text("area",userModel.getArea()));
doc.add(SearchUtils.Text("city",userModel.getCity()));
doc.add(SearchUtils.Text("work",userModel.getWork()));
doc.add(SearchUtils.Text("birthday",userModel.getBirthday()));
doc.add(SearchUtils.Text("intro",userModel.getIntro()));
doc.add(SearchUtils.Text("signatures",userModel.getSignatures()));
if(Validator.isEmpty(userModel.getLastLoginIp())){
userModel.setLastLoginIp(userModel.getRegIp());
}
userModel.setLastLoginIp(userModel.getLastLoginIp().trim());
if(!Validator.isEmpty(userModel.getLastLoginIp())
&&!userModel.getLastLoginIp().equalsIgnoreCase("127.0.0.1")
&&!userModel.getLastLoginIp().equalsIgnoreCase("null"))
{
//logger.debug("lastLoginIp: "+userModel.getLastLoginIp());
List<String> list = IPSeeker.getInstance().IPParser(userModel.getLastLoginIp());
if(!Validator.isEmpty(list)){
for(int i=0; i<list.size(); i++){
switch(i){
case 0:
doc.add(SearchUtils.Text("city_",list.get(i)));
break;
case 1:
doc.add(SearchUtils.Text("area_",list.get(i)));
break;
}
}
}
}
writer.addDocument(doc);
this.getUserIndexedService().clear(userModel.getUserId());
File.createFile(MINID_FILE,String.valueOf(userModel.getUserId()),"gbk",true);
}
@Override
public void createIndex(boolean iscreate, int minId) {
super.setProgress(SEARCH_USER,0,0);
int maxBufferedDocs = getBasicService().findOnly().getMaxBufferedDocs();
int mergeFactor = getBasicService().findOnly().getMergeFactor();
int maxFieldLength = getBasicService().findOnly().getMaxFieldLength();
File.createFolder(INDEXPATH_USER);
IndexWriter writer;
try {
logger.debug("iscreate: "+iscreate);
writer = SearchUtils.getIndexWriter(TEMPPATH_USER, iscreate);
writer.setMaxBufferedDocs(maxBufferedDocs); // Defalut 10
writer.setMergeFactor(mergeFactor); // Defalut 10
writer.setMaxFieldLength(maxFieldLength);
int rows = 1000;
UserParameter param = new UserParameter();
param.setOrderBy(new Byte((byte) 8));
param.setRows(new Integer(rows));
if(minId>0){//不重复索引
param.setIsIndexed(new Boolean(false));
}
//param.setMinId(new Integer(minId));
long count = this.getUserService().countByParameter(param);
int pages = (int) (count/rows);
if(count%rows!=0){
pages++;
}
if(pages==0&&count>0){
pages = 1;
}
int indexed = 0;
logger.debug("count="+count);
outer:
for(int page=1; page<=pages; page++){
param.setPage(new Integer(page));
List<UserModel> list = this.getUserService().findByParameter(param);
if(!Validator.isEmpty(list)){
for(int i=0; i<list.size(); i++){
//logger.debug("count="+count+" / pages="+pages+" / userId="+list.get(i).getUserId());
indexed++;
this.addDocs(list.get(i),writer);
super.setProgress(SEARCH_USER,count,indexed);
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_USER);
File.deleteFolder(INDEXPATH_USER);
logger.info("移动新索引到目录:"+INDEXPATH_USER);
File.copyFolder(TEMPPATH_USER,INDEXPATH_USER);
logger.info("开启索引服务器!");
CANSEARCH = 1;
logger.info("索引创建完成,本次任务结束!");
STATE=2;
}else{
logger.info("索引创建任务被强迫终止,本次任务结束!");
}
} catch (IOException e) {
logger.error(e.toString());
} catch (ClubException e) {
logger.error(e.toString());
}
}
@Override
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,"gbk");
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","gbk",true);
createIndex(true,0);
} catch (IOException e) {
logger.error(e.toString());
}
}
STATE=2;
}
@Override
public void deleteIndex(int id) {
CANSEARCH = 0;
if(new java.io.File(INDEXPATH_USER+"segments").exists()){
SearchUtils.delete(id,"userId",INDEXPATH_USER);
}
if(new java.io.File(TEMPPATH_USER+"segments").exists()){
SearchUtils.delete(id,"userId",TEMPPATH_USER);
}
CANSEARCH = 1;
}
@Override
public void updateIndex(int id) {
if(!new java.io.File(INDEXPATH_USER+"segments").exists()
||!new java.io.File(TEMPPATH_USER+"segments").exists()){
return ;
}
CANSEARCH = 0;
SearchUtils.delete(id,"userId",INDEXPATH_USER);
SearchUtils.delete(id,"userId",TEMPPATH_USER);
UserModel userModel = this.getUserService().findById(id);
IndexWriter writer;
try {
writer = SearchUtils.getIndexWriter(TEMPPATH_USER, false);
this.addDocs(userModel,writer);
writer.optimize();
writer.close();
writer = SearchUtils.getIndexWriter(INDEXPATH_USER, false);
this.addDocs(userModel,writer);
writer.optimize();
writer.close();
this.getUserService().updateIsIndexedByUserId(id,true);
} catch (IOException e) {
this.getUserService().updateIsIndexedByUserId(id,false);
logger.error(e.toString());
} catch (ClubException e) {
logger.error(e.toString());
}
CANSEARCH = 1;
}
private String getHighlightStr(Highlighter highlighter, String name, String str){
str = StringHelper.htmlEncoder(str);
TokenStream stream = AnalyzerFactory.getAnalyzer().tokenStream(name,new StringReader(str));
try {
str = highlighter.getBestFragments(stream,str,50,"...");
} catch (IOException e) {
logger.error(e.toString());
}
return str;
}
@Override
public List<UserModel> results(SearchParameter param) {
if(CANSEARCH==0){
return null;
}
super.totalrows = 0;
super.runtimed = 0;
long begin = System.currentTimeMillis();
List<UserModel> 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>();
if(!Validator.isEmpty(param.getKeys())){
fields.add("userName");
boosts.add(new Float(0.9));
keys.add(param.getKeys());
flags.add(Occur.SHOULD);
fields.add("penName");
boosts.add(new Float(0.8));
keys.add(param.getKeys());
flags.add(Occur.SHOULD);
fields.add("area");
boosts.add(new Float(0.5));
keys.add(param.getKeys());
flags.add(Occur.SHOULD);
fields.add("city");
boosts.add(new Float(0.1));
keys.add(param.getKeys());
flags.add(Occur.SHOULD);
}
if(!Validator.isEmpty(param.getSex())){
if(param.getSex().equalsIgnoreCase("1")){
fields.add("sex");
boosts.add(new Float(0.3));
keys.add(param.getSex());
flags.add(Occur.MUST);
}
else if(param.getSex().equalsIgnoreCase("2")){
fields.add("sex");
boosts.add(new Float(0.3));
keys.add(param.getSex());
flags.add(Occur.MUST);
}
}
if(!Validator.isEmpty(param.getIp())){
List<String> ipaddress = IPSeeker.getInstance().IPParser(param.getIp());
if(!Validator.isEmpty(ipaddress)){
for(int i=0; i<ipaddress.size(); i++){
switch(i){
case 0:
fields.add("area_");
boosts.add(new Float(0.8));
keys.add(ipaddress.get(i));
flags.add(Occur.SHOULD);
continue;
case 1:
fields.add("city_");
boosts.add(new Float(0.8));
keys.add(ipaddress.get(i));
flags.add(Occur.SHOULD);
continue;
}
}
}
}
Searcher searcher = new IndexSearcher(INDEXPATH_USER);
list = new ArrayList<UserModel>();
Query query = MultiFiledQuery.parse(keys, fields, flags, boosts, AnalyzerFactory.getAnalyzer());
logger.debug(query.toString());
Hits hits = searcher.search(query);
SimpleHTMLFormatter sf = new SimpleHTMLFormatter("<font class=\"red\">","</font>");
QueryScorer scorer = new QueryScorer(query);
Highlighter highlighter = null;
if(!Validator.isEmpty(param.getHighlight())&¶m.getHighlight()){
highlighter = new Highlighter(sf, scorer);
Fragmenter fragmenter = new SimpleFragmenter(100);
highlighter.setTextFragmenter(fragmenter);
}
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 userId_ = doc.get("userId");
int userId = TypeChange.stringToInt(userId_);
UserModel userModel = this.getUserService().findById(userId);
if(!Validator.isEmpty(userModel)){
if(!Validator.isEmpty(param.getHighlight())&¶m.getHighlight()){
userModel.setUserName(this.getHighlightStr(highlighter,"userName",userModel.getUserName()));
userModel.setPenName(this.getHighlightStr(highlighter,"penName",userModel.getPenName()));
userModel.setArea(this.getHighlightStr(highlighter,"area",userModel.getArea()));
}
list.add(userModel);
}
} catch (IOException e) {
logger.error(e.toString());
}
}
}
searcher.close();
} catch (IOException e) {
logger.error(e.toString());
} catch (org.apache.lucene.queryParser.ParseException e) {
logger.error(e.toString());
}
long end = System.currentTimeMillis();
super.runtimed = (end - begin);
return list;
}
@Override
public int getTotalrows() {
return super.totalrows;
}
@Override
public void setTotalrows(int totalrows) {
super.totalrows = totalrows;
}
@Override
public long getRuntimed() {
return super.runtimed;
}
public static BasicInfoService getBasicService() {
return ServiceWrapper.<BasicInfoService>getSingletonInstance(ServiceLocator.BASICINFO);
}
public UserService getUserService() {
return ServiceWrapper.<UserService>getSingletonInstance(ServiceLocator.USER);
}
public UserIndexedService getUserIndexedService() {
return ServiceWrapper.<UserIndexedService>getSingletonInstance(ServiceLocator.USER_INDEXED);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -