- 浏览: 27896 次
- 性别:
- 来自: 北京
最新评论
-
Josun:
谦虚学习中
[译稿]软件编程21法则 -
hyx0914:
呵呵,学习中
[译稿]软件编程21法则 -
mzba520:
不错。同意
[译稿]软件编程21法则 -
bornwan:
开发一个傻瓜都会使用的软件,只有傻瓜愿意使用它。
这条严重同意 ...
[译稿]软件编程21法则 -
yin_bp:
呵呵,开发一个傻瓜都会使用的软件,只有傻瓜愿意使用它。
[译稿]软件编程21法则
全文分两部分:
一:Lucene简介
Lucene版本:3.0.2
全文检索大体分两个部分:索引创建(Indexing)和搜索索引(Search)
1. 索引过程:
1) 有一系列被索引文件(此处所指即数据库数据)
2) 被索引文件经过语法分析和语言处理形成一系列词(Term)。
3) 经过索引创建形成词典和反向索引表。
4) 通过索引存储将索引写入硬盘。
2. 搜索过程:
a) 用户输入查询语句。
b) 对查询语句经过语法分析和语言分析得到一系列词(Term)。
c) 通过语法分析得到一个查询树。
d) 通过索引存储将索引读入到内存。
e) 利用查询树搜索索引,从而得到每个词(Term)的文档链表,对文档链表进行交,差,并得到结果文档。
f) 将搜索到的结果文档对查询的相关性进行排序。
g) 返回查询结果给用户。
• 索引过程如下:
◦ 创建一个IndexWriter用来写索引文件,它有几个参数,INDEX_DIR就是索引文件所存放的位置,Analyzer便是用来对文档进行词法分析和语言处理的。
◦ 创建一个Document代表我们要索引的文档。
◦ 将不同的Field加入到文档中。我们知道,一篇文档有多种信息,如题目,作者,修改时间,内容等。不同类型的信息用不同的Field来表示,在本例子中,一共有两类信息进行了索引,一个是文件路径,一个是文件内容。其中FileReader的SRC_FILE就表示要索引的源文件。
◦ IndexWriter调用函数addDocument将索引写到索引文件夹中。
• 搜索过程如下:
◦ IndexReader将磁盘上的索引信息读入到内存,INDEX_DIR就是索引文件存放的位置。
◦ 创建IndexSearcher准备进行搜索。
◦ 创建Analyer用来对查询语句进行词法分析和语言处理。
◦ 创建QueryParser用来对查询语句进行语法分析。
◦ QueryParser调用parser进行语法分析,形成查询语法树,放到Query中。
◦ IndexSearcher调用search对查询语法树Query进行搜索,得到结果TopScoreDocCollector。
二:代码示例(本文重点部分)
1) 首先是连接数据库的jdbc配置文件信息以及存放索引文件的路径配置信息
jdbc.driverClassName = com.mysql.jdbc.Driver jdbc.url = jdbc:mysql://192.168.0.1/dbname?autoReconnect=true&characterEncoding=utf8 jdbc.username = root jdbc.password = password jdbc.maxIdle = 2 jdbc.maxActive = 4 jdbc.maxWait = 5000 jdbc.validationQuery = select 0 res.index.indexPath = D\:\\apache-tomcat-6.0.18\\webapps\\test\\testHome\\search\\res\\index1 res.index.mainDirectory = D\:\\apache-tomcat-6.0.18\\webapps\\test\\testHome\\search\\res
2) 读取资源文件的工具类:
package com.test.common; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Properties; /** * PropertiesUtil.java * @version 1.0 * @createTime 读取配置文件信息类 */ public class PropertiesUtil { private static String defaultPropertyFilePath = "/test.properties"; private static Map<String,Properties> ppsMap = new HashMap<String,Properties>(); /** * 读取默认文件的配置信息,读key返回value * @param key * @return value */ public static final String getPropertyValue(String key) { Properties pps = getPropertyFile(defaultPropertyFilePath); return pps == null ? null : pps.getProperty(key); } /** * 传入filePath读取指定property文件,读key返回value * @param propertyFilePath * @param key * @return value */ public static String getPropertyValue(String propertyFilePath,String key) { if(propertyFilePath == null) { propertyFilePath = defaultPropertyFilePath; } Properties pps = getPropertyFile(propertyFilePath); return pps == null ? null : pps.getProperty(key); } /** * 根据path返回property文件,并保存到HashMap中,提高效率 * @param propertyFilePath * @return */ public static Properties getPropertyFile(String propertyFilePath) { if(propertyFilePath == null) { return null; } Properties pps = ppsMap.get(propertyFilePath); if(pps == null) { InputStream in = PropertiesUtil.class.getResourceAsStream(propertyFilePath); pps = new Properties(); try { pps.load(in); } catch (IOException e) { e.printStackTrace(); } ppsMap.put(propertyFilePath, pps); } return pps; } }
3) Jdbc连接数据库获取Connection工具类,不做分析,直接上代码
package com.test.common; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * JdbcUtil.java * @version 1.0 * @createTime JDBC获取Connection工具类 */ public class JdbcUtil { private static Connection conn = null; private static final String URL; private static final String JDBC_DRIVER; private static final String USER_NAME; private static final String PASSWORD; static { URL = PropertiesUtil.getPropertyValue("jdbc.url"); JDBC_DRIVER = PropertiesUtil.getPropertyValue("jdbc.driverClassName"); USER_NAME = PropertiesUtil.getPropertyValue("jdbc.username"); PASSWORD = PropertiesUtil.getPropertyValue("jdbc.password"); } public static Connection getConnection() { try { Class.forName(JDBC_DRIVER); conn = DriverManager.getConnection(URL, USER_NAME, PASSWORD); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; } }
4) 万事具备,只欠东风了,下面是核心部分,方法都有注释,不多说了,一步步来,我想肯定是没有问题的。代码如下:
package com.test.lucene.logic; import java.io.File; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.Field.TermVector; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.Searcher; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; import org.wltea.analyzer.lucene.IKAnalyzer; import org.wltea.analyzer.lucene.IKSimilarity; import com.test.common.JdbcUtil; import com.test.common.PropertiesUtil; import com.test.lucene.model.SearchBean; /** * SearchLogic.java * @version 1.0 * @createTime Lucene数据库检索 */ public class SearchLogic { private static Connection conn = null; private static Statement stmt = null; private static ResultSet rs = null; private String searchDir = PropertiesUtil.getPropertyValue("res.index.indexPath"); private static File indexFile = null; private static Searcher searcher = null; private static Analyzer analyzer = null; /** 索引页面缓冲 */ private int maxBufferedDocs = 500; /** * 获取数据库数据 * @return ResultSet * @throws Exception */ public List<SearchBean> getResult(String queryStr) throws Exception { List<SearchBean> result = null; conn = JdbcUtil.getConnection(); if(conn == null) { throw new Exception("数据库连接失败!"); } String sql = "select articleid,title_en,title_cn,abstract_en,abstract_cn from p2p_jour_article"; try { stmt = conn.createStatement(); rs = stmt.executeQuery(sql); this.createIndex(rs); //给数据库创建索引,此处执行一次,不要每次运行都创建索引,以后数据有更新可以后台调用更新索引 TopDocs topDocs = this.search(queryStr); ScoreDoc[] scoreDocs = topDocs.scoreDocs; result = this.addHits2List(scoreDocs); } catch(Exception e) { e.printStackTrace(); throw new Exception("数据库查询sql出错! sql : " + sql); } finally { if(rs != null) rs.close(); if(stmt != null) stmt.close(); if(conn != null) conn.close(); } return result; } /** * 为数据库检索数据创建索引 * @param rs * @throws Exception */ private void createIndex(ResultSet rs) throws Exception { Directory directory = null; IndexWriter indexWriter = null; try { indexFile = new File(searchDir); if(!indexFile.exists()) { indexFile.mkdir(); } directory = FSDirectory.open(indexFile); analyzer = new IKAnalyzer(); indexWriter = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED); indexWriter.setMaxBufferedDocs(maxBufferedDocs); Document doc = null; while(rs.next()) { doc = new Document(); Field articleid = new Field("articleid", String.valueOf(rs .getInt("articleid")), Field.Store.YES, Field.Index.NOT_ANALYZED, TermVector.NO); Field abstract_cn = new Field("abstract_cn", rs .getString("abstract_cn") == null ? "" : rs .getString("abstract_cn"), Field.Store.YES, Field.Index.ANALYZED, TermVector.NO); doc.add(articleid); doc.add(abstract_cn); indexWriter.addDocument(doc); } indexWriter.optimize(); indexWriter.close(); } catch(Exception e) { e.printStackTrace(); } } /** * 搜索索引 * @param queryStr * @return * @throws Exception */ private TopDocs search(String queryStr) throws Exception { if(searcher == null) { indexFile = new File(searchDir); searcher = new IndexSearcher(FSDirectory.open(indexFile)); } searcher.setSimilarity(new IKSimilarity()); QueryParser parser = new QueryParser(Version.LUCENE_30,"abstract_cn",new IKAnalyzer()); Query query = parser.parse(queryStr); TopDocs topDocs = searcher.search(query, searcher.maxDoc()); return topDocs; } /** * 返回结果并添加到List中 * @param scoreDocs * @return * @throws Exception */ private List<SearchBean> addHits2List(ScoreDoc[] scoreDocs ) throws Exception { List<SearchBean> listBean = new ArrayList<SearchBean>(); SearchBean bean = null; for(int i=0 ; i<scoreDocs.length; i++) { int docId = scoreDocs[i].doc; Document doc = searcher.doc(docId); bean = new SearchBean(); bean.setArticleid(doc.get("articleid")); bean.setAbstract_cn(doc.get("abstract_cn")); listBean.add(bean); } return listBean; } public static void main(String[] args) { SearchLogic logic = new SearchLogic(); try { Long startTime = System.currentTimeMillis(); List<SearchBean> result = logic.getResult("急性 肺 潮气量 临床试验"); int i = 0; for(SearchBean bean : result) { if(i == 10) break; System.out.println("bean.name " + bean.getClass().getName() + " : bean.articleid " + bean.getArticleid() + " : bean.abstract_cn " + bean.getAbstract_cn()); i++; } System.out.println("searchBean.result.size : " + result.size()); Long endTime = System.currentTimeMillis(); System.out.println("查询所花费的时间为:" + (endTime-startTime)/1000); } catch (Exception e) { e.printStackTrace(); System.out.println(e.getMessage()); } } }
5) 第四步用到了一个SearchBean,其实这就是一个javabean文件,包含两个String类型(articleid和abstract_cn)的set、get方法,自己回去补上吧。
顺便说下数据库表结构:
tablename随便取,但要跟上面查询中的表对应
表字段:articleid int 类型
abstract_cn varchar类型
对表字段没有太严格的定义,本来就是用来测试的。
6) 最后给大家提供所使用到的jar包列表:
IKAnalyzer3.2.5Stable.jar(一位好心人建议我升级一下jar包,呵呵,最新的jar包名为:IKAnalyzer3.2.8.jar ,谢谢了!)
lucene-analyzers-3.0.2
lucene-core-3.0.2
lucene-highlighter-3.0.2
lucene-memory-3.0.2
lucene-queries-3.0.2
mysql-connector-java-5.0.8-bin
好了,有兴趣的人可以试试吧,代码都经过我测试过了,虽然有些地方代码结构不是特别完整,但只是入门用而已。先有了一个成功能够运行的例子之后才有更多的心情去接着学下去,~_~
评论
<div class="quote_div">
<p>全文分两部分:</p>
<p>一:Lucene简介</p>
<p> Lucene版本:3.0.2</p>
<p class="MsoPlainText"><span> 全文检索大体分两个部分:索引创建(<span lang="EN-US">Indexing</span>)和搜索索引(<span lang="EN-US">Search</span>)</span></p>
<p><span lang="EN-US"> 1. </span><span>索引过程:</span></p>
<p class="MsoPlainText"><span lang="EN-US"> 1) </span><span>有一系列被索引文件(此处所指即数据库数据)</span></p>
<p class="MsoPlainText"><span lang="EN-US"> 2) </span><span>被索引文件经过语法分析和语言处理形成一系列词<span lang="EN-US">(Term)</span>。</span></p>
<p class="MsoPlainText"><span lang="EN-US"> 3) </span><span>经过索引创建形成词典和反向索引表。</span></p>
<p class="MsoPlainText"><span lang="EN-US"> 4) </span><span>通过索引存储将索引写入硬盘。</span></p>
<p class="MsoPlainText"><span lang="EN-US"> 2. </span><span>搜索过程:</span></p>
<p class="MsoPlainText"><span lang="EN-US"> a) </span><span>用户输入查询语句。</span></p>
<p class="MsoPlainText"><span lang="EN-US"> b) </span><span>对查询语句经过语法分析和语言分析得到一系列词<span lang="EN-US">(Term)</span>。</span></p>
<p class="MsoPlainText"><span lang="EN-US"> c) </span><span>通过语法分析得到一个查询树。</span></p>
<p class="MsoPlainText"><span lang="EN-US"> d) </span><span>通过索引存储将索引读入到内存。</span></p>
<p class="MsoPlainText"><span lang="EN-US"> e) </span><span>利用查询树搜索索引,从而得到每个词<span lang="EN-US">(Term)</span>的文档链表,对文档链表进行交,差,并得到结果文档。</span></p>
<p class="MsoPlainText"><span lang="EN-US"> f) </span><span>将搜索到的结果文档对查询的相关性进行排序。</span></p>
<p class="MsoPlainText"><span lang="EN-US"> g) </span><span>返回查询结果给用户。</span></p>
<p class="MsoPlainText"> </p>
<p class="MsoPlainText"> </p>
<p class="MsoPlainText"><span> </span><span>• </span><span>索引过程如下:</span></p>
<p class="MsoPlainText"><span> ◦</span><span> 创建一个<span lang="EN-US">IndexWriter</span>用来写索引文件,它有几个参数,<span lang="EN-US">INDEX_DIR</span>就是索引文件所存放的位置,<span lang="EN-US">Analyzer</span>便是用来对文档进行词法分析和语言处理的。</span></p>
<p class="MsoPlainText"><span> ◦</span><span> 创建一个<span lang="EN-US">Document</span>代表我们要索引的文档。</span></p>
<p class="MsoPlainText"><span> ◦</span><span> 将不同的<span lang="EN-US">Field</span>加入到文档中。我们知道,一篇文档有多种信息,如题目,作者,修改时间,内容等。不同类型的信息用不同的<span lang="EN-US">Field</span>来表示,在本例子中,一共有两类信息进行了索引,一个是文件路径,一个是文件内容。其中<span lang="EN-US">FileReader</span>的<span lang="EN-US">SRC_FILE</span>就表示要索引的源文件。</span></p>
<p class="MsoPlainText"><span> ◦</span><span lang="EN-US"> IndexWriter</span><span>调用函数<span lang="EN-US">addDocument</span>将索引写到索引文件夹中。</span></p>
<p class="MsoPlainText"><span> • 搜索过程如下:</span></p>
<p class="MsoPlainText"><span> ◦</span><span lang="EN-US"> IndexReader</span><span>将磁盘上的索引信息读入到内存,<span lang="EN-US">INDEX_DIR</span>就是索引文件存放的位置。</span></p>
<p class="MsoPlainText"><span> ◦</span><span> 创建<span lang="EN-US">IndexSearcher</span>准备进行搜索。</span></p>
<p class="MsoPlainText"><span> ◦</span><span> 创建<span lang="EN-US">Analyer</span>用来对查询语句进行词法分析和语言处理。</span></p>
<p class="MsoPlainText"><span> ◦</span><span> 创建<span lang="EN-US">QueryParser</span>用来对查询语句进行语法分析。</span></p>
<p class="MsoPlainText"><span> ◦</span><span lang="EN-US"> QueryParser</span><span>调用<span lang="EN-US">parser</span>进行语法分析,形成查询语法树,放到<span lang="EN-US">Query</span>中。</span></p>
<p><span> ◦</span><span lang="EN-US"> IndexSearcher</span><span lang="EN-US">调用<span lang="EN-US">search</span>对查询语法树<span lang="EN-US">Query</span>进行搜索,得到结果TopScoreDocCollector</span><span>。</span></p>
<p>二:代码示例(本文重点部分)</p>
<p> 1) 首先是连接数据库的jdbc配置文件信息以及存放索引文件的路径配置信息</p>
<pre name="code" class="test.properties">jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://192.168.0.1/dbname?autoReconnect=true&characterEncoding=utf8
jdbc.username = root
jdbc.password = password
jdbc.maxIdle = 2
jdbc.maxActive = 4
jdbc.maxWait = 5000
jdbc.validationQuery = select 0
res.index.indexPath = D\:\\apache-tomcat-6.0.18\\webapps\\test\\testHome\\search\\res\\index1
res.index.mainDirectory = D\:\\apache-tomcat-6.0.18\\webapps\\test\\testHome\\search\\res
</pre>
<p> 2) 读取资源文件的工具类:</p>
<pre name="code" class="java">package com.test.common;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* PropertiesUtil.java
* @version 1.0
* @createTime 读取配置文件信息类
*/
public class PropertiesUtil {
private static String defaultPropertyFilePath = "/test.properties";
private static Map<String,Properties> ppsMap = new HashMap<String,Properties>();
/**
* 读取默认文件的配置信息,读key返回value
* @param key
* @return value
*/
public static final String getPropertyValue(String key) {
Properties pps = getPropertyFile(defaultPropertyFilePath);
return pps == null ? null : pps.getProperty(key);
}
/**
* 传入filePath读取指定property文件,读key返回value
* @param propertyFilePath
* @param key
* @return value
*/
public static String getPropertyValue(String propertyFilePath,String key) {
if(propertyFilePath == null) {
propertyFilePath = defaultPropertyFilePath;
}
Properties pps = getPropertyFile(propertyFilePath);
return pps == null ? null : pps.getProperty(key);
}
/**
* 根据path返回property文件,并保存到HashMap中,提高效率
* @param propertyFilePath
* @return
*/
public static Properties getPropertyFile(String propertyFilePath) {
if(propertyFilePath == null) {
return null;
}
Properties pps = ppsMap.get(propertyFilePath);
if(pps == null) {
InputStream in = PropertiesUtil.class.getResourceAsStream(propertyFilePath);
pps = new Properties();
try {
pps.load(in);
} catch (IOException e) {
e.printStackTrace();
}
ppsMap.put(propertyFilePath, pps);
}
return pps;
}
}
</pre>
<p> 3) Jdbc连接数据库获取Connection工具类,不做分析,直接上代码</p>
<pre name="code" class="java">package com.test.common;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* JdbcUtil.java
* @version 1.0
* @createTime JDBC获取Connection工具类
*/
public class JdbcUtil {
private static Connection conn = null;
private static final String URL;
private static final String JDBC_DRIVER;
private static final String USER_NAME;
private static final String PASSWORD;
static {
URL = PropertiesUtil.getPropertyValue("jdbc.url");
JDBC_DRIVER = PropertiesUtil.getPropertyValue("jdbc.driverClassName");
USER_NAME = PropertiesUtil.getPropertyValue("jdbc.username");
PASSWORD = PropertiesUtil.getPropertyValue("jdbc.password");
}
public static Connection getConnection() {
try {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(URL, USER_NAME, PASSWORD);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
}
</pre>
<p> 4) 万事具备,只欠东风了,下面是核心部分,方法都有注释,不多说了,一步步来,我想肯定是没有问题的。代码如下:</p>
<pre name="code" class="java">package com.test.lucene.logic;
import java.io.File;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.TermVector;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKSimilarity;
import com.test.common.JdbcUtil;
import com.test.common.PropertiesUtil;
import com.test.lucene.model.SearchBean;
/**
* SearchLogic.java
* @version 1.0
* @createTime Lucene数据库检索
*/
public class SearchLogic {
private static Connection conn = null;
private static Statement stmt = null;
private static ResultSet rs = null;
private String searchDir = PropertiesUtil.getPropertyValue("res.index.indexPath");
private static File indexFile = null;
private static Searcher searcher = null;
private static Analyzer analyzer = null;
/** 索引页面缓冲 */
private int maxBufferedDocs = 500;
/**
* 获取数据库数据
* @return ResultSet
* @throws Exception
*/
public List<SearchBean> getResult(String queryStr) throws Exception {
List<SearchBean> result = null;
conn = JdbcUtil.getConnection();
if(conn == null) {
throw new Exception("数据库连接失败!");
}
String sql = "select articleid,title_en,title_cn,abstract_en,abstract_cn from p2p_jour_article";
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
this.createIndex(rs); //给数据库创建索引,此处执行一次,不要每次运行都创建索引,以后数据有更新可以后台调用更新索引
TopDocs topDocs = this.search(queryStr);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
result = this.addHits2List(scoreDocs);
} catch(Exception e) {
e.printStackTrace();
throw new Exception("数据库查询sql出错! sql : " + sql);
} finally {
if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(conn != null) conn.close();
}
return result;
}
/**
* 为数据库检索数据创建索引
* @param rs
* @throws Exception
*/
private void createIndex(ResultSet rs) throws Exception {
Directory directory = null;
IndexWriter indexWriter = null;
try {
indexFile = new File(searchDir);
if(!indexFile.exists()) {
indexFile.mkdir();
}
directory = FSDirectory.open(indexFile);
analyzer = new IKAnalyzer();
indexWriter = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
indexWriter.setMaxBufferedDocs(maxBufferedDocs);
Document doc = null;
while(rs.next()) {
doc = new Document();
Field articleid = new Field("articleid", String.valueOf(rs
.getInt("articleid")), Field.Store.YES,
Field.Index.NOT_ANALYZED, TermVector.NO);
Field abstract_cn = new Field("abstract_cn", rs
.getString("abstract_cn") == null ? "" : rs
.getString("abstract_cn"), Field.Store.YES,
Field.Index.ANALYZED, TermVector.NO);
doc.add(articleid);
doc.add(abstract_cn);
indexWriter.addDocument(doc);
}
indexWriter.optimize();
indexWriter.close();
} catch(Exception e) {
e.printStackTrace();
}
}
/**
* 搜索索引
* @param queryStr
* @return
* @throws Exception
*/
private TopDocs search(String queryStr) throws Exception {
if(searcher == null) {
indexFile = new File(searchDir);
searcher = new IndexSearcher(FSDirectory.open(indexFile));
}
searcher.setSimilarity(new IKSimilarity());
QueryParser parser = new QueryParser(Version.LUCENE_30,"abstract_cn",new IKAnalyzer());
Query query = parser.parse(queryStr);
TopDocs topDocs = searcher.search(query, searcher.maxDoc());
return topDocs;
}
/**
* 返回结果并添加到List中
* @param scoreDocs
* @return
* @throws Exception
*/
private List<SearchBean> addHits2List(ScoreDoc[] scoreDocs ) throws Exception {
List<SearchBean> listBean = new ArrayList<SearchBean>();
SearchBean bean = null;
for(int i=0 ; i<scoreDocs.length; i++) {
int docId = scoreDocs[i].doc;
Document doc = searcher.doc(docId);
bean = new SearchBean();
bean.setArticleid(doc.get("articleid"));
bean.setAbstract_cn(doc.get("abstract_cn"));
listBean.add(bean);
}
return listBean;
}
public static void main(String[] args) {
SearchLogic logic = new SearchLogic();
try {
Long startTime = System.currentTimeMillis();
List<SearchBean> result = logic.getResult("急性 肺 潮气量 临床试验");
int i = 0;
for(SearchBean bean : result) {
if(i == 10) break;
System.out.println("bean.name " + bean.getClass().getName()
+ " : bean.articleid " + bean.getArticleid()
+ " : bean.abstract_cn " + bean.getAbstract_cn());
i++;
}
System.out.println("searchBean.result.size : " + result.size());
Long endTime = System.currentTimeMillis();
System.out.println("查询所花费的时间为:" + (endTime-startTime)/1000);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
</pre>
<p> 5) 第四步用到了一个SearchBean,其实这就是一个javabean文件,包含两个String类型(articleid和abstract_cn)的set、get方法,自己回去补上吧。</p>
<p> 顺便说下数据库表结构:</p>
<p> tablename随便取,但要跟上面查询中的表对应</p>
<p> 表字段:articleid int 类型</p>
<p> abstract_cn varchar类型</p>
<p> 对表字段没有太严格的定义,本来就是用来测试的。</p>
<p> 6) 最后给大家提供所使用到的jar包列表:</p>
<p> IKAnalyzer3.2.5Stable.jar(一位好心人建议我升级一下jar包,呵呵,最新的jar包名为:IKAnalyzer3.2.8.jar ,谢谢了!)</p>
<p> lucene-analyzers-3.0.2</p>
<p> lucene-core-3.0.2</p>
<p> lucene-highlighter-3.0.2</p>
<p> lucene-memory-3.0.2</p>
<p> lucene-queries-3.0.2</p>
<p> mysql-connector-java-5.0.8-bin</p>
<p> 好了,有兴趣的人可以试试吧,代码都经过我测试过了,虽然有些地方代码结构不是特别完整,但只是入门用而已。先有了一个成功能够运行的例子之后才有更多的心情去接着学下去,~_~</p>
</div>
<p> </p>
回到正题,字面理解"Lucene检索数据库"是lucene能利用db的索引能力做检索,实在没看出切合题意之处。如果这是Luence入门文章貌似又不够详细,可以参考已有的文章。
哎呀,我说哥们,干嘛把一篇简简单单的文章往那么深入的方面想,并不是每个人都跟你一样对全文检索有深入的理解或者接触广。还得照顾一下刚开始学又没有这方面资料的人吧,适时也要站在基层的角度考虑一下老百姓的需求,我这篇文章的目的就出于此,对于初学者入门并没有误导的层面。
标题很清晰的写着“入门篇”,index融合问题不在本文范围之内。
Lucene检索数据库的含义指的是用户界面输入关键字,从数据库中的表数据进行检索相关包含用户输入关键字的数据,并返回给用户,该检索过程包含两步
1.将相关的表数据根据一定的条件过滤后生产结果集,然后由Lucene创建索引,生成索引文件
2.根据用户提供的关键字从索引文件中查询数据,这个返回的数据便是用户需要查询的结果。
我认为很切合题意。
好吧,聊聊检索,提到检索肯定是有数据源了,按标题和文章提到的数据源应该是数据库吧,暂且不提数据的数据从何而来。对Lucene来说,不论xml、csv或db数据源没什么区别,核心在创建了索引之后跟数据源已经关系不大(尤其是Field.Store.YES这种保存字段值的方式),在次之后的检索是lucene自己的能力。
lz提到的两步对此也描述的很清楚,外加文中注释:
//给数据库创建索引,此处执行一次,不要每次运行都创建索引,以后数据有更新可以后台调用更新索引
看来lz也认同,正常情况下建立索引和检索应该是分开的。
回到正题,字面理解"Lucene检索数据库"是lucene能利用db的索引能力做检索,实在没看出切合题意之处。如果这是Luence入门文章貌似又不够详细,可以参考已有的文章。
http://www.iteye.com/search?type=all&query=lucene&sort=
http://www.iteye.com/search?type=all&query=lucene+%E5%85%A5%E9%97%A8
(1) 如何区相同数据库中的不同的表,简历索引库的时候,可不可以把根据不同的表,创建不同的索引库,查询的时候,可不可以根据不同的需求查询不同的索引库
(2)不同数据库情况下存放不同的表,需求同上
1)Lucene创建索引是由用户自己定义存储索引路径,所以不同的表数据可以分别创建不同的索引文件以区分,自然在查询的时候便可逻辑控制查询哪些数据。
2)只要数据能查出来,就可以满足需求。
大概意思:
取DB数据 -----> Lucene建索引 ------>Lucene检索
整个流程Lucene跟DB没半毛钱关系,更谈不上检索数据库了,跟正常的Lucene应用有甚区别。
没找到“Lucene检索数据库”的核心内容
不知道 兄弟说的 “Lucene检索数据库”的核心内容 具体指什么?
乍看“Lucene检索数据库”这标题,第一感觉是Lucene和DB融合,尤其是index融合,有nosql倾向。实际内容相去甚远呐,DB检索跟Lucene没什么联系,名不副实。
标题很清晰的写着“入门篇”,index融合问题不在本文范围之内。
Lucene检索数据库的含义指的是用户界面输入关键字,从数据库中的表数据进行检索相关包含用户输入关键字的数据,并返回给用户,该检索过程包含两步
1.将相关的表数据根据一定的条件过滤后生产结果集,然后由Lucene创建索引,生成索引文件
2.根据用户提供的关键字从索引文件中查询数据,这个返回的数据便是用户需要查询的结果。
我认为很切合题意。
大概意思:
取DB数据 -----> Lucene建索引 ------>Lucene检索
整个流程Lucene跟DB没半毛钱关系,更谈不上检索数据库了,跟正常的Lucene应用有甚区别。
没找到“Lucene检索数据库”的核心内容
不知道 兄弟说的 “Lucene检索数据库”的核心内容 具体指什么?
乍看“Lucene检索数据库”这标题,第一感觉是Lucene和DB融合,尤其是index融合,有nosql倾向。实际内容相去甚远呐,DB检索跟Lucene没什么联系,名不副实。
大概意思:
取DB数据 -----> Lucene建索引 ------>Lucene检索
整个流程Lucene跟DB没半毛钱关系,更谈不上检索数据库了,跟正常的Lucene应用有甚区别。
没找到“Lucene检索数据库”的核心内容
不知道 兄弟说的 “Lucene检索数据库”的核心内容 具体指什么?
大概意思:
取DB数据 -----> Lucene建索引 ------>Lucene检索
整个流程Lucene跟DB没半毛钱关系,更谈不上检索数据库了,跟正常的Lucene应用有甚区别。
没找到“Lucene检索数据库”的核心内容
(1) 如何区相同数据库中的不同的表,简历索引库的时候,可不可以把根据不同的表,创建不同的索引库,查询的时候,可不可以根据不同的需求查询不同的索引库
(2)不同数据库情况下存放不同的表,需求同上
相关推荐
《最新全文检索 Lucene-5.2.1 入门经典实例》 Lucene是一个开源的全文检索库,由Apache软件基金会开发,广泛应用于各种信息检索系统。在5.2.1版本中,Lucene提供了更为高效和强大的搜索功能,为开发者提供了构建...
学习全文检索的最佳入门之原始代码(非 Lucene)。全文检索系统的实现技术分为三个方面:关系型全文检索系统、层次型全文检索系统、面向对象的全文检索系统及自动标引技术。 针对全文数据系统的构建,提出全文检索...
Lucene是中国大百科全书式的全文检索库,它在Java世界中扮演着核心角色,为开发者提供了强大的...总之,Lucene是一个强大且灵活的全文检索工具,通过这个入门小例子,你可以逐步揭开其神秘的面纱,踏入文本搜索的世界。
**标题:“Lucene-入门”** Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发并维护。它是Java编写的一个开源项目,被广泛应用于构建搜索引擎或者在大型数据集上进行全文检索。Lucene提供了丰富的搜索...
5. `org.apache.lucene.document`:文档的存储结构,Document对象代表一篇文档,由多个Field组成,Field对应文档的不同部分,支持不同的数据类型。 在开发过程中,开发者需要对输入数据进行预处理,如通过Analyzer...
在IT领域,搜索引擎的开发与优化是一项关键技术,而Apache Lucene作为一款高性能、全文本搜索库,是许多开发者进行文本检索的首选工具。本文将深入探讨如何使用Lucene5来创建一个基本的索引,帮助初学者入门。 首先...
2. **入门篇**:讲解如何搭建一个基本的Lucene应用,包括创建索引、执行查询以及结果排序。此外,还会讨论如何处理多字段索引和多语言文本。 3. **进阶篇**:深入探讨高级主题,如性能优化、分布式搜索(通过Solr或...
这篇博文将带你深入理解Lucene的基本概念和使用方式,帮助你快速入门并掌握其核心功能。 1. **Lucene简介** Lucene是Apache软件基金会的一个开源项目,它提供了高性能、可扩展的信息检索服务。作为一个纯Java库,...
"ElasticSearch 入门篇" ElasticSearch 是一个基于 Lucene 的搜索服务器,提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。ElasticSearch 是用 Java 开发的,并作为 Apache 许可条款下的开放...
团队参考了多部技术书籍,包括《Java程序语言设计(基础篇)》、《Java经典实例》、《开发者突击—struts2核心技术与Java EE整合开发实战》、《CSS入门经典》、《XML技术应用》以及《征服Ajax+Lucene构建搜索引擎》...
Elasticsearch是一种基于Lucene的搜索引擎,它提供了一个分布式多用户的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可下的开源代码发布。它的主要特点包括:分布式实时文件...
对于中文处理,需要考虑汉字的分词规则,如使用jieba分词库。 3. **索引系统**:核心是倒排表结构。每个词项对应一个倒排列表,记录了这个词在哪些文档中出现及其位置信息。倒排表的构建和管理涉及数据结构优化,如...
### 使用Hibernate Search入门详解 #### 引言 Hibernate Search作为Hibernate Core的重要补充,为持久化领域模型提供了全文搜索查询的功能,将Lucene的搜索特性引入到Hibernate的世界中。本篇文章将深入探讨如何从...
- **搜索引擎与Lucene**:掌握文本搜索,实现全文检索。 - **Seam&Jboss**:理解Seam框架,熟悉Jboss应用服务器。 ### Java学习路径总结 Java学习之路漫长而充满挑战,但只要按照科学的学习路径,从基础开始,逐步...
**Elasticsearch 入门指南** Elasticsearch 是一个基于 Lucene 的开源全文搜索引擎,它以其分布式的实时性、灵活性和强大的分析能力而备受推崇。在这个 is421-elasticsearch 项目中,我们将深入探讨如何从零开始...