- 浏览: 447886 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
飞天奔月:
我来个简单点的代码 使用 LinkedHashSetpubli ...
ArrayList去重 -
飞天奔月:
public static <T> List< ...
ArrayList去重 -
aaron7524:
事务隔离级别 -
月陨殇:
wlh269 写道rswh110 写道lz内容写的不错,就是略 ...
事务隔离级别 -
lnx1824:
我的更奇怪,在本地静态的可以,放jetty里的页面后就不然,都 ...
JS得到上传图片尺寸
公司项目:portal中期刊文章内容作为大字段存储在Oracle中,首页有一个搜索功能:要求将所有包括搜索字段的文章的标题列出来(文章的内容存储在Oracle的CLOB字段中),也就是要用Lucene实现对数据库的大字段进行索引(索引通过计划任务定时建立索引)和搜索。。。
==================定时建立索引文件:===============
Main方法:
定时调用建立索引任务:
建立索引的核心实现:
配置文件管理类:
常量配置
数据类型处理类:
配置文件 :
==================搜索类:===============
核心搜索类:
配置文件管理类:
配置文件:zxt_index.xml
==================定时建立索引文件:===============
Main方法:
package zxt.lucene.index; import java.util.Timer; public class IndexerServer { /** * 定时调用建立索引任务 * @author wulihai * @create 2009-06-02 */ public static void main(String[] args) { String propFile = "directory.properties"; Config.setConfigFileName(propFile); Timer timer = new Timer(); LuceneDBIndexerTask luceneTask=LuceneDBIndexerTask.getInstance(); timer.scheduleAtFixedRate(luceneTask, 0,DataTypeUtil.toLong(Constant.CREATE_INDEX_SLEEP_TIME)); } }
定时调用建立索引任务:
package zxt.lucene.index; import java.util.Timer; public class IndexerServer { /** * 定时调用建立索引任务 * @author wulihai * @create 2009-06-02 */ public static void main(String[] args) { String propFile = "directory.properties"; Config.setConfigFileName(propFile); Timer timer = new Timer(); LuceneDBIndexerTask luceneTask=LuceneDBIndexerTask.getInstance(); timer.scheduleAtFixedRate(luceneTask, 0,DataTypeUtil.toLong(Constant.CREATE_INDEX_SLEEP_TIME)); } }
建立索引的核心实现:
package zxt.lucene.index; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.TimerTask; import oracle.sql.CLOB; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; /** * 建立索引的任务类 * @author wulihai * @create 2009-06-02 */ public class LuceneDBIndexerTask extends TimerTask { //缺省索引目录 private static String DEFAULT_INDEX_DIR="C:\\IndexDB"; //临时索引目录的父目录 private File parentDir=null; //被搜索的索引文件 private static LuceneDBIndexerTask index=new LuceneDBIndexerTask(); //构造方法 private LuceneDBIndexerTask(){ String dirStr=Constant.INDEX_STORE_DIRECTORY; if(dirStr!=null&&!"".equals(dirStr)){ this.parentDir=new File(dirStr); }else{ this.parentDir=new File(DEFAULT_INDEX_DIR); } if(!this.parentDir.exists()){ this.parentDir.mkdir(); } } /** * 单实例访问接口 * @return */ public static LuceneDBIndexerTask getInstance(){ return index; } /** * 锁定目录以及文件 * 只允许单线程访问 * */ /*public synchronized void singleRunning(){ if(flag==false){ flag=true; run(parentDir); } }*/ /** * 为数据库字段建立索引 */ public void run() { System.out.println("====LuceneDBIndexerTask$run()==============="); System.out.println("~~~开始建立索引文件~~~~~~~~~~~~~~~"); Connection conn=null; Statement stmt=null; ResultSet rs=null; try { Class.forName(Constant.DB_DRIVER_STRING); conn = DriverManager.getConnection(Constant.DB_URI_STRING, Constant.DB_USERNAME, Constant.DB_PWD); stmt = conn.createStatement(); rs = stmt.executeQuery(Constant.DB_QUERY_STRING); File file=new File(parentDir+File.separator+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+File.separator); if(!file.exists()){ file.mkdir(); } IndexWriter writer = new IndexWriter(file,new StandardAnalyzer(), true); long startTime = new Date().getTime(); while (rs.next()) { Document doc = new Document(); doc.add(new Field("ARTICLEID", rs.getString("ARTICLEID"), Field.Store.YES,Field.Index.TOKENIZED)); doc.add(new Field("TITLE", rs.getString("TITLE"), Field.Store.YES,Field.Index.TOKENIZED)); doc.add(new Field("USERNAME", rs.getString("USERNAME"), Field.Store.YES,Field.Index.TOKENIZED)); doc.add(new Field("USERID", rs.getString("USERID"), Field.Store.YES,Field.Index.TOKENIZED)); //对日期建立索引 String createdate=new SimpleDateFormat("yyyy-MM-dd").format(rs.getTimestamp("CREATEDATE")); doc.add(new Field("CREATEDATE", createdate, Field.Store.YES,Field.Index.TOKENIZED)); //对大字段建立索引 BufferedReader in=null; String content=""; CLOB clob = (CLOB) rs.getClob("CONTENT"); if (clob != null) { //得到一个读入流 in=new BufferedReader(clob.getCharacterStream()); StringWriter out=new StringWriter(); int c; while((c=in.read())!=-1){ out.write(c); } content=out.toString(); } doc.add(new Field("CONTENT", content, Field.Store.YES, Field.Index.TOKENIZED)); writer.addDocument(doc); } writer.optimize(); writer.close(); //测试一下索引的时间 long endTime = new Date().getTime(); System.out.println("索引文件"+file.getPath()+"建立成功..."); System.out.println("这花费了" + (endTime - startTime) + " 毫秒来把文档增加到索引里面去!"); //判断文件目录file下的文件个数如果大于3,就将文件建立最早的文件给删除掉 checkFiles(parentDir); } catch (IOException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }finally{ try { if(rs!=null){ rs.close(); } if(stmt!=null){ stmt.close(); } if(conn!=null){ conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } /** * 判断文件目录file下的文件个数如果大于3,就将文件建立最早的文件给删除掉 */ public void checkFiles(File dir) { int length=dir.listFiles().length; while(length>3){ //删除生成最早的文件 File [] files=dir.listFiles(); String[] names=dir.list(); Arrays.sort(names); File deletefile=files[0]; deleteDirectory(deletefile); length--; } } /* * 递归删除一个目录以及下面的文件 */ public boolean deleteDirectory(File path) { if( path.exists() ) { File[] files = path.listFiles(); for(int i=0; i<files.length; i++) { if(files[i].isDirectory()) { deleteDirectory(files[i]); } else { //删除文件 files[i].delete(); } } } //删除目录 boolean hasdelete=path.delete(); if(hasdelete){ System.out.println("删除索引目录"+path); } return hasdelete; } public static void main(String[] args) { new LuceneDBIndexerTask().run(); } }
配置文件管理类:
package zxt.lucene.index; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * * @author wulihai * @create 2009-06-02 * */ public class Config { private static Config cfg = null; private static String configFileName = null; private Properties props; public Config() { props = new java.util.Properties(); } /** * 单例访问接口 * @return */ public synchronized static Config getInstance() { if (cfg == null) { cfg = new Config(); cfg.loadConfig(); return cfg; } else { return cfg; } } private int loadConfig() { if (configFileName != null || configFileName.length() > 0) { InputStream inputStream = Config.class.getClassLoader() .getResourceAsStream("directory.properties"); System.out.println("configFileName=" + configFileName); try { props.load(inputStream); } catch (IOException e) { e.printStackTrace(); } return 1; } return 0; } public static void setConfigFileName(String cfg) { configFileName = cfg; } public String getProperty(String keyName) { return props.getProperty(keyName); } }
常量配置
package zxt.lucene.index; /** * 常量配置类 * * @author wulihai * @create 2009-06-02 */ public class Constant { // 隔多长时间建立一次索引 public static final String CREATE_INDEX_SLEEP_TIME = Config.getInstance() .getProperty("create_index_sleep_time"); // 索引文件存放路径 public static final String INDEX_STORE_DIRECTORY = Config.getInstance() .getProperty("index_store_directory"); //数据库驱动程序 public static final String DB_DRIVER_STRING = Config.getInstance() .getProperty("db_driver_string"); //数据库连接URI public static final String DB_URI_STRING = Config.getInstance() .getProperty("db_uri_string"); //数据库连接username public static final String DB_USERNAME= Config.getInstance() .getProperty("db_username"); //数据库连接pwd public static final String DB_PWD= Config.getInstance() .getProperty("db_pwd"); //数据库查询语句db_query_str public static final String DB_QUERY_STRING= Config.getInstance() .getProperty("db_query_string"); }
数据类型处理类:
package zxt.lucene.index; /** * 数据类型转换工具类 * @author wulihai * @create 2009-06-02 */ public class DataTypeUtil { /** * 将对象转换为整数型 * @param o 源对象 * @return 对应的Long值,如果出错,则返回Long.MIN_VALUE */ public static long toLong(Object o) { if (o == null) { throw new IllegalArgumentException("该对象为空"); } String s = o.toString(); try { return Long.parseLong(s); } catch (Exception ex) { return Long.MAX_VALUE; } } }
配置文件 :
#== the directory for store lucene-index ========# index_store_directory=D:/lucene/indexDB/ #======== two hours ========# #create_index_sleep_time=7200000 #======== two minutes ========# create_index_sleep_time=120000 db_driver_string=oracle.jdbc.driver.OracleDriver db_uri_string=jdbc:oracle:thin:@localhost:1521:lportal db_username=lportal db_pwd=lportal db_query_string=SELECT * from journalarticle
==================搜索类:===============
核心搜索类:
package com.liferay.portal.util; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.Hits; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import com.liferay.portlet.journal.model.JournalArticle; /** * 负责搜索的类 */ public class LuceneDBQuery { private static LuceneDBQuery search = new LuceneDBQuery(); // 构造方法 private LuceneDBQuery() { } /** * 单实例访问接口 * * @return */ public static LuceneDBQuery getInstance() { return search; } /** * 搜索方法 * * @throws java.text.ParseException * @throws Exception */ public List search(String queryString) { int count = 0; long startTime = new Date().getTime(); Hits hits = null; // 搜索目录 File searchDir = null; Query query = null; InputStream inputStream=null;; String filePath="index.xml"; String indexDir=""; indexDir= LuceneDBQueryUtil.getIndexPath(); if (indexDir != null && !"".equals(indexDir)) { searchDir = new File(indexDir); if(!searchDir.exists()){ searchDir.mkdir(); } } // 这里注意索引存放的目录的父目录 // searchDir=new File("E:\\index\\indexDB\\"); File targetDir = getTargetDir(searchDir); IndexSearcher searcher = null; List results = new ArrayList(); try { Directory dir=FSDirectory.getDirectory(targetDir,false); searcher = new IndexSearcher(dir); } catch (Exception e1) { e1.printStackTrace(); System.out.println("创建索引对象出现异常..."); } Analyzer analyzer = new StandardAnalyzer(); // 构建查询对象Query,对CONTENT字段进行搜索 QueryParser qp = new QueryParser("CONTENT", analyzer); try { query = qp.parse(queryString); } catch (ParseException e1) { e1.printStackTrace(); } if (searcher != null) { // 得到搜索结果Hits try { hits = searcher.search(query); } catch (IOException e1) { System.out.println("查询索引库出现异常..."); e1.printStackTrace(); } // 查到的记录条数 count = hits.length(); if (hits.length() > 0) { for (int i = 0; i < hits.length(); i++) {// 输出搜索信息 JournalArticle article = new JournalArticle(); Document document = null; try { document = hits.doc(i); } catch (Exception e1) { System.out.println("返回查询结果集出现异常..."); e1.printStackTrace(); } try { article.setDisplayDate(new SimpleDateFormat("yyyyMMdd") .parse(document.get("CREATEDATE"))); article.setCreateDate(new SimpleDateFormat("yyyyMMdd") .parse(document.get("CREATEDATE"))); } catch (java.text.ParseException e) { e.printStackTrace(); } article.setTitle(document.get("TITLE")); article.setArticleId(document.get("ARTICLEID")); article.setUserName(document.get("USERNAME")); article.setUserId(document.get("USERID")); results.add(article); } // 测试一下索引的时间 long endTime = new Date().getTime(); System.out.println("查询过程花费了" + (endTime - startTime) + " 毫秒!"); } else { System.out.println("0个结果!"); } } return results; } /** * 确定搜索索引所在目录目录 */ private File getTargetDir(File dir) { int length = dir.listFiles().length; File searchFile = null; // length=3的时候最多 // 同时搜索和同时建索引的时候会出现length=4 if (length >= 2) { // 找到次最新建立的索引文件 String[] names = dir.list(); Arrays.sort(names); searchFile = new File(dir + File.separator + names[length - 2]); } if (length == 1) { File files[] = dir.listFiles(); searchFile = files[0]; } if (length == 0) { // 如果没有索引文件则,建立第一个索引 // TestDBIndexer.getInstance().isInstanceRunning(); // search(); } return searchFile; } // // public static void main(String[] args) throws Exception { // new LuceneDBQuery().search("纳税人"); // } }
配置文件管理类:
package com.liferay.portal.util; import java.io.IOException; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.input.SAXBuilder; public class LuceneDBQueryUtil { public static String getIndexPath(){ String filePath = "zxt_index.xml"; String indexPath=""; SAXBuilder builder = new SAXBuilder(false); try { Document doc = builder.build(Thread.currentThread().getContextClassLoader().getResource(filePath)); Element rootElement = doc.getRootElement(); Element index=rootElement.getChild("index"); indexPath=index.getText(); System.out.println(indexPath); } catch (JDOMException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return indexPath; } }
配置文件:zxt_index.xml
<?xml version="1.0" encoding="UTF-8"?> <list> <index>D:\\index\\IndexDB</index> </list>
发表评论
-
做文件传输服务后注意小事项
2010-06-30 15:50 9911.检查上传下载文件内容不能为空,为空则不上传或者下载; 2. ... -
Liferay Portal二次开发指南
2009-05-29 22:24 2738Liferay Portal二次开发指南Liferay Por ... -
单点登陆的概念
2009-05-06 18:06 808单点登陆的概念: 当一 ... -
怎样安装和配置Tomcat Admin
2009-04-14 00:19 1092怎样安装和配置Tomcat Adm ... -
freemarker小例子
2009-03-28 17:39 96101.在D盘下创建一个目录D:\\freemarker 2.在以 ... -
WebService测试
2009-02-28 15:47 1330WebSevice测试 -
使用xdocLet自动生成: 类的映射文件/ hibernate配置文件
2009-02-15 17:50 16081.用户类User对应组织机构中的类Person:使用了一对 ... -
分页标签pager-taglib的使用
2009-02-14 09:40 12501、拷贝pager-taglib.jar包 2、在JSP页面中 ...
相关推荐
Lucene非常复杂,你需要深入的了解检索相关知识来理解它是如何工作的。 Elasticsearch也是使用Java编写并使用Lucene来建立索引并实现搜索功能,但是它的目的是通过简单连贯的RESTful API让全文搜索变得简单并隐藏...
基于 Rada Mihalcea 和 Paul Tarau 所做的工作。 方法论取自: : 使用 OpenNLP 库来分离句子和 Lucene 库来去除停用词和标记化。 TextSummary 的结果将与其他各种文本摘要器进行比较: 新闻文章使用: Java...
2.1.1 准备工作环境(10分钟) 5 2.1.2 编写代码(15分钟) 6 2.1.3 发布运行(5分钟) 9 2.2 搜索引擎基本技术 14 2.2.1 网络蜘蛛 14 2.2.2 全文索引结构 14 2.2.3 Lucene 全文检索引擎 15 2.2.4 Nutch网络搜索软件...
当前/以前的工作总结: 在 Cleartrip Travels [],我是开发航班/酒店搜索/预订系统的后端团队的一员。 我在飞行队。 我和我的导师一起使用 ITA API 在 Common Lisp 中设计和实现了国际航班搜索产品。 我还致力于构建...
利用java.url中的类实现Spider程序与外界通讯,以及处理网页中的URL连接,对蜘蛛程序的核心类(通讯核心、蜘蛛程序工作核心),资源索引的建立与搜索新型了详细的研究。 通过设计分析,完成了自己的蜘蛛爬行程序。...
准备工作(sql文件在项目里面) 安装 Jdk8 安装 Maven 准备 IDE (如果你不看源码,可以忽略下面的步骤,直接通过Maven编译war包:mvn clean package -DskipTests) IDE 需要配置的东西 编码方式设为UTF-8 配置...
4.4.1 开发准备工作 88 4.4.2 消息封装类 88 4.4.3 封装消息处理工具 89 4.4.4 使用CoreServlet类完成消息的接收与响应 93 4.4.5 使用CoreService类完成消息的处理 95 4.4.6 部署应用及测试体验 ...
谈谈你对Lucene和solr的理解 谈谈你对ActiveMQ的理解 Spring的IOC,DI和AOP 谈谈你对webservice和dubbo的理解 谈谈你的SOA的理解。 谈谈你对freemarker的理解 谈谈你对springMVC的理解 谈谈你对mybatis的理解 ...
本文是Meltwater的工程师结合工作中实践,分享了Elasticsearch调优秘笈,以及要绕过的一些陷阱。 Meltwater每天要处理数百万量级的帖子数据,因此需要一种能处理该量级数据的存储和检索技术。 从0.11.X 版本开始...
第一章绪论............................................................第五章总结和展望.............................................................................................……51 5.1结论.............
这是一个典型的基于ASP.Net技术的OA协同办公项目,包含了权限管理、公告管理、文档管理、工作流、论坛管理、新闻模块管理、人员管理等典型的OA系统模块。 3、数据采集和邮件群发。这是一个基于多线程的邮件营销平台...