- 浏览: 455647 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
飞天奔月:
我来个简单点的代码 使用 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 10291.检查上传下载文件内容不能为空,为空则不上传或者下载; 2. ... -
Liferay Portal二次开发指南
2009-05-29 22:24 2760Liferay Portal二次开发指南Liferay Por ... -
单点登陆的概念
2009-05-06 18:06 828单点登陆的概念: 当一 ... -
怎样安装和配置Tomcat Admin
2009-04-14 00:19 1118怎样安装和配置Tomcat Adm ... -
freemarker小例子
2009-03-28 17:39 96301.在D盘下创建一个目录D:\\freemarker 2.在以 ... -
WebService测试
2009-02-28 15:47 1451WebSevice测试 -
使用xdocLet自动生成: 类的映射文件/ hibernate配置文件
2009-02-15 17:50 16311.用户类User对应组织机构中的类Person:使用了一对 ... -
分页标签pager-taglib的使用
2009-02-14 09:40 12721、拷贝pager-taglib.jar包 2、在JSP页面中 ...
相关推荐
创建索引是Lucene工作的第一步。这涉及到添加文档到一个名为“IndexWriter”的对象,该对象负责将文档转化为倒排索引。例如: ```java Directory indexDir = FSDirectory.open(Paths.get("index_path")); ...
2. **工作流程**:使用 Lucene 首先需要创建索引,这涉及到对原始数据的分析、分词、建立倒排索引等步骤。然后,用户可以提交查询,Lucene 将根据查询条件在索引中查找匹配的文档。 ### 二、Lucene 2.4 API 使用 #...
### Lucene3源码分析知识点概述 #### 一、全文检索的基本原理 ##### 1....以上是对Lucene3源码分析的一些关键知识点总结,通过对这些概念和技术的理解,可以更好地掌握Lucene的工作原理及其应用。
在深入理解Lucene的工作原理时,我们首先要关注的是其核心算法。 一、单个索引的构建 在Lucene中,索引构建的核心算法是快速排序算法。当新文档被添加到索引时,它们首先被分到不同的段(Segment),每个段都是一个...
**Lucene全文检索引擎** Lucene是Apache软件基金会的一个开源项目,...总结来说,Lucene是一个强大的全文检索引擎,通过理解和掌握其工作原理及API,开发者可以构建出高效、灵活的搜索功能,满足各种复杂的搜索需求。
**Lucene 全文搜索引擎实例:Java Lucene 实例** Lucene 是 Apache 软件基金会的一个开源项目,它提供了一个高性能、可扩展的信息...通过实践这个实例,你可以深入掌握 Lucene 的工作原理,并将其应用到你的项目中。
总结,Weblucene作为一款开源的站内搜索引擎,为开发者提供了构建高效、灵活搜索功能的工具。通过了解其工作原理,掌握部署和使用方法,以及探索进阶特性,你可以为你的网站创造出一流的搜索体验。无论是初创的小型...
二、Lucene工作流程 1. 创建索引:首先,使用IndexWriter创建一个索引,将文档的字段添加到索引中。这个过程中,分词器会对文档内容进行处理。 2. 建立倒排索引:索引的核心是倒排索引,它将每个词(Term)映射到...
该文档详细阐述了Lucene的架构设计,包括其核心组件如Analyzer(分析器)、Document(文档)、IndexWriter(索引写入器)和Searcher(搜索器)的工作原理。理解这些组件如何协同工作,有助于你更好地利用Lucene进行...
- **作用**:此包中的类主要用于对需要建立索引的文本进行分词、过滤等预处理工作。它是Lucene全文检索的基础。 - **核心类**: - **Analyzer**:抽象类,管理对文本内容的切分词规则。Analyzer类用于将文档分割成...
总结,"lucene-2.4.0 jar 包"是 Lucene 库的一个早期版本,尽管现在有更先进的版本,但其核心概念和机制对于学习和理解 Lucene 的工作原理仍然具有很高的价值。开发者可以利用这个包来构建自己的全文搜索引擎,或者...
总结,Lucene是一个强大且灵活的全文检索库,它不仅提供了核心的搜索功能,还允许开发者通过定制化实现各种复杂的搜索需求。在实际项目中,结合如Solr或Elasticsearch这样的高级搜索服务器,可以构建出更强大的企业...
总结,Lucene 4.7.0提供了完整的全文索引和搜索解决方案,通过各种组件协同工作,能够有效地处理文本数据,实现高效、精准的搜索,并且通过高亮显示提升用户体验。对于Java开发者来说,熟练掌握Lucene 4.7.0的使用,...
二、Lucene工作流程 1. 创建索引(Indexing):首先,通过Analyzer处理文档内容,将文本分解为关键词,然后将这些关键词及其关联的文档信息存储到索引中。 2. 查询(Query):用户输入查询字符串,经过同样的分词...
总结,Lucene 5为开发者提供了强大且灵活的全文检索功能,通过深入学习其源码,尤其是拼音检索和分词器的运用,可以有效地提升搜索质量和用户体验。不断探索和实践,才能充分挖掘Lucene的潜力,为各种信息检索应用...
5. **优化和调优**:根据实际需求,可能还需要进行一些优化工作,例如调整`HanLP`的分词参数,或者对`Lucene5`的索引配置进行微调,以提高搜索效率和精度。 在`Lucene5DemoHanLP`这个压缩包中,应该包含了实现上述...
总结来说,".NET Lucene 源代码"为我们提供了一个深入了解和学习全文搜索引擎技术的宝贵资源。通过深入研究,我们可以掌握如何在.NET环境中高效地构建和使用搜索引擎,提升开发项目的搜索功能。同时,这也是一次难得...