lucene索引并搜索mysql数据库[转]
由于对lucene比较感兴趣,本人在网上找了点资料,终于成功地用lucene对mysql数据库进行索引创建并成功搜索,先总结如下:
首先介绍一个jdbc工具类,用于得到Connection对象:
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.SQLException;
- /**
- * JdbcUtil.java
- * @version 1.0
- * @createTime JDBC获取Connection工具类
- */
- public class JdbcUtil {
- private static Connection conn = null;
- private static final String URL = "jdbc:mysql://127.0.0.1/project?autoReconnect=true&characterEncoding=utf8";
- private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
- private static final String USER_NAME = "root";
- private static final String 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;
- }
- }
然后就是本文的主要内容了,对数据库信息进行索引与对索引进行搜索:
- 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.*;
- 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;
- /**
- * 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 = "E:\\Test\\Index";
- 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 id, username, password, type from account";
- 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 id = new Field("id", String.valueOf(rs.getInt("id")), Field.Store.YES, Field.Index.NOT_ANALYZED, TermVector.NO);
- Field username = new Field("username", rs.getString("username") == null ? "" : rs.getString("username"), Field.Store.YES,Field.Index.ANALYZED, TermVector.NO);
- doc.add(id);
- doc.add(username);
- 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,"username",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.setId(doc.get("id"));
- bean.setUsername(doc.get("username"));
- 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.id " + bean.getId()+ " : bean.username " + bean.getUsername());
- 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());
- }
- }
- }
对了上面的类还用到了一个javabean类,如下:
- public class SearchBean {
- private String id;
- private String username;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- }
这些代码大部分都是我在网上找到的doc文档中复制粘贴而来,本着“拿来主义”,我对这些代码修改不大,经测试,这些代码能够正常运行。
写了几篇博客,对lucene的使用方式也越来越清楚,在这里也很有必要总结一下:
使用lucene包括两个步骤,分别是索引和搜索。
•索引过程如下:
◦ 创建一个IndexWriter用来写索引文件,它有几个参数,INDEX_DIR就是索引文件所存放的位置,Analyzer便是用来对文档进行词法分析和语言处理的。
◦ 创建一个Document代表我们要索引的文档。
◦ 将不同的Field加入到文档中。我们知道,一篇文档有多种信息,如题目,作者,修改时间,内容等。不同类型的信息用不同的Field来表示。
◦ IndexWriter调用函数addDocument将索引写到索引文件夹中。
•搜索过程如下:
◦ IndexReader将磁盘上的索引信息读入到内存,INDEX_DIR就是索引文件存放的位置。
◦ 创建IndexSearcher准备进行搜索。
◦ 创建Analyer用来对查询语句进行词法分析和语言处理。
◦ 创建QueryParser用来对查询语句进行语法分析。
◦ QueryParser调用parser进行语法分析,形成查询语法树,放到Query中。
◦ IndexSearcher调用search对查询语法树Query进行搜索,得到结果TopScoreDocCollector。
对了,必须说一下,上面的例子还用到了一个新的jar包IKAnalyzer.jar包,它是一个开源的中文分词器,如果不使用这个分词器,那么将无法解析中文,比如说我的第一篇关于Lucene的博客就无法解析中文字符串!
lucene索引并搜索mysql数据库[转]的更多相关文章
- 理解Lucene索引与搜索过程中的核心类
理解索引过程中的核心类 执行简单索引的时候需要用的类有: IndexWriter.Directory.Analyzer.Document.Field 1.IndexWriter IndexWr ...
- PHP搜索MYSQL数据库加分页浏览小结
PHP搜索加分页浏览小结: 1 分页后再做搜索 2 这里对于url的拼接,以及模糊查询,搜索时候的显示添加,SQL语句的拼接 3 对于页面传递过来的超级链接的变量,如果不存在就要设置,对于可能抛出异常 ...
- Lucene 索引功能
Lucene 数据建模 基本概念 文档(doc): 文档是 Lucene 索引和搜索的原子单元,文档是一个包含多个域的容器. 域(field): 域包含“真正的”被搜索的内容,每一个域都有一个标识名称 ...
- mysql数据库详解
001 数据库应用系统设计 1.规划 2.需求分析 3.概念模型设计 4.逻辑设计 5.物理设计 6.程序编制及调试 7.运行及维护. 002 创建数据库 CREATE DAT ...
- MySQL数据库和InnoDB存储引擎文件
参数文件 当MySQL示例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数,这些参数通常定义了某种内存结构有多大等.在默认情况下,MySQL实例会按照一定 ...
- lucene索引
一.lucene索引 1.文档层次结构 索引(Index):一个索引放在一个文件夹中: 段(Segment):一个索引中可以有很多段,段与段之间是独立的,添加新的文档可能产生新段,不同的段可以合并成一 ...
- MYSQL数据库的日志文件
日志文件:用来记录MySQL实例对某种条件做出响应时写入的文件.如错误日志文件.二进制日志文件.慢查询日志文件.查询日志文件等. 错误日志 show variables like 'log_error ...
- MySQL数据库文件
MySQL数据库文件 本文档从MySQL数据库和存储引擎层面介绍各种类型的文件. 参数文件(my.cnf) 错误日志(error log) 二进制日志文件(binary log) 慢查询日志(slow ...
- 用Lucene.net对数据库建立索引及搜索<转>
用Lucene.net对数据库建立索引及搜索 最近我一直在研究 Lucene.net ,发现Lucene.net对数据库方面建索引的文章在网上很少见,其实它是可以对数据库进行索引的,我闲着没事,写了个 ...
随机推荐
- 1.MVC框架开发(初识MVC)
1.约定大于配置 Content:存放静态文件(样式表.静态图片等) Controllers:存放控制器类 Models:存放数据模型文件 Scripts:存放脚本文件 Views:存放视图文件,里面 ...
- 安装plsql
sqlplus能登录,服务器.网络.tns配置应该都是好的,应该就是plsql本身的问题 问下安装路径在哪? 注意安装路径中不能有括号,不要安装在C:\Program Files (x86)目录下面
- REST响应处理
JAX-RS 2.0 支持4种返回值类型的响应,分别是无返回值.返回Response类实例.返回GenericEntity类实例和返回自定义类实例. 1.在返回值类型是VOID的响应中,其响应实体为空 ...
- DM8168 解码显示模块代码阅读分析
解码/显示概述:从共享文件夹获取H264流,对264流进行解析,生成hdr文件,hdr文件中包含每一帧的信息,将视频帧信息存放在A8核分配的共享内存空间,供其他核或其他的link调用,M3 Video ...
- C语言程序设计做题笔记之C语言基础知识(上)
C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行事.并且C是相当灵活的,用于执行计算机程序能完成的几乎 ...
- 矩阵分解(rank decomposition)文章代码汇总
矩阵分解(rank decomposition)文章代码汇总 矩阵分解(rank decomposition) 本文收集了现有矩阵分解的几乎所有算法和应用,原文链接:https://sites.goo ...
- javascript 字符串转数字
//把str转换为数字的方式,想起很久以前的一个面试题,说字符转数字的方式有哪些,现在想了想 var str1='4.88',str2='4.8xx'; console.log(parseInt(st ...
- 【POJ 3487】 The Stable Marriage Problem (稳定婚姻问题)
The Stable Marriage Problem Description The stable marriage problem consists of matching members o ...
- 【HDU 4352】 XHXJ's LIS (数位DP+状态压缩+LIS)
XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- [LeetCode#161] One Edit Distance
Problem: Given two strings S and T, determine if they are both one edit distance apart. General Anal ...