需求

很多时候我们在用数据库的需要使用模糊查询,我们一般会使用like语句来做,然而这样的做的效率不是很多(很抱歉我们亲自去测,很多都这么说的),那么使用Lucene来检索的话,效率会高很多。

lucene结合数据库步骤

写一段传统的JDBC程序,将每条的用户信息从数据库读取出来

针对每条用户记录,建立一个lucene document

Document doc = new Document();

并根据你的需要,将用户信息的各个字段对应luncene document中的field 进行添加,如:

doc.add(new Field(“NAME”,”USERNAME”,Field.Store.YES,Field.Index.UN_TOKENIZED));

然后将该条doc加入到索引中, 如: luceneWriter.addDocument(doc);

这样就建立了lucene的索引库

编写对索引库的搜索程序(看lucene文档),通过对lucene的索引库的查找,你可以快速找到对应记录的ID

通过ID到数据库中查找相关记录

注意

在索引的过程中,可以使用增量的方式建立索引,这样对已经索引的记录不在建立索引。实现思路:保存上次(lasttime)的新增时候的id,在建立索引的时候,值查询这个id之后的记录进行索引,更新这个记录下来的id,在数据库数据修改时候,针对这个数据制作索引的修改

操作实例

package lucene_demo05;

import java.io.IOException;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import org.apache.lucene.analysis.Analyzer;

import org.apache.lucene.document.Document;

import org.apache.lucene.document.Field;

import org.apache.lucene.document.TextField;

import org.apache.lucene.index.CorruptIndexException;

import org.apache.lucene.index.DirectoryReader;

import org.apache.lucene.index.IndexWriter;

import org.apache.lucene.index.IndexWriterConfig;

import org.apache.lucene.index.IndexWriterConfig.OpenMode;

import org.apache.lucene.queryparser.classic.ParseException;

import org.apache.lucene.queryparser.classic.QueryParser;

import org.apache.lucene.search.IndexSearcher;

import org.apache.lucene.search.Query;

import org.apache.lucene.search.ScoreDoc;

import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;

import org.apache.lucene.store.Directory;

import org.apache.lucene.store.RAMDirectory;

import org.apache.lucene.util.Version;

import org.wltea.analyzer.lucene.IKAnalyzer;

/**

*

* Lucene与数据库结合使用

*

* @author YipFun

*/

public class LuceneDemo05 {

private static final String driverClassName="com.mysql.jdbc.Driver";

private static final String url="jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8";

private static final String username="****";

private static final String password="****";

private static final Version version = Version.LUCENE_4_9;

private Directory directory = null;

private DirectoryReader ireader = null;

private IndexWriter iwriter = null;

private IKAnalyzer analyzer;

private Connection conn;

public LuceneDemo05() {

directory = new RAMDirectory();

}

public IndexSearcher getSearcher(){

try {

if(ireader==null) {

ireader = DirectoryReader.open(directory);

} else {

DirectoryReader tr = DirectoryReader.openIfChanged(ireader) ;

if(tr!=null) {

ireader.close();

ireader = tr;

}

}

return new IndexSearcher(ireader);

} catch (CorruptIndexException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

public Connection getConnection(){

if(this.conn == null){

try {

Class.forName(driverClassName);

conn = DriverManager.getConnection(url, username, password);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

}

}

return conn;

}

private IKAnalyzer getAnalyzer(){

if(analyzer == null){

return new IKAnalyzer();

}else{

return analyzer;

}

}

public void createIndex(){

Connection conn = getConnection();

ResultSet rs = null;

PreparedStatement pstmt = null;

if(conn == null){

System.out.println("get the connection error...");

return ;

}

String sql = "select * from t_user";

try {

pstmt = conn.prepareStatement(sql);

rs = pstmt.executeQuery();

IndexWriterConfig iwConfig = new IndexWriterConfig(version, getAnalyzer());

iwConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);

iwriter = new IndexWriter(directory,iwConfig);

while(rs.next()){

int id = rs.getInt(1);

String name = rs.getString(2);

String psd = rs.getString(3);

Document doc = new Document();

doc.add(new TextField("id", id+"",Field.Store.YES));

doc.add(new TextField("name", name+"",Field.Store.YES));

doc.add(new TextField("psd", psd+"",Field.Store.YES));

iwriter.addDocument(doc);

}

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}finally{

try {

if(iwriter != null)

iwriter.close();

rs.close();

pstmt.close();

if(!conn.isClosed()){

conn.close();

}

} catch (IOException e) {

e.printStackTrace();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

public void searchByTerm(String field,String keyword,int num) throws InvalidTokenOffsetsException{

IndexSearcher isearcher = getSearcher();

Analyzer analyzer = getAnalyzer();

//使用QueryParser查询分析器构造Query对象

QueryParser qp = new QueryParser(version,field,analyzer);

//这句所起效果?

qp.setDefaultOperator(QueryParser.OR_OPERATOR);

try {

Query query = qp.parse(keyword);

ScoreDoc[] hits;

//注意searcher的几个方法

hits = isearcher.search(query, null, num).scoreDocs;

System.out.println("the ids is =");

for (int i = 0; i < hits.length; i++) {

Document doc = isearcher.doc(hits[i].doc);

System.out.print(doc.get("id")+" ");

}

} catch (IOException e) {

e.printStackTrace();

} catch (ParseException e) {

e.printStackTrace();

}

}

public static void main(String[] args) throws InvalidTokenOffsetsException {

LuceneDemo05 ld = new LuceneDemo05();

ld.createIndex();

ld.searchByTerm("name", "Bruce", 100);

}

}

索引之后就可以拿到需要id,这个时候按id查询数据库的记录,就快多了。

思考

这是对单表的数据进行索引,当我们的业务复杂的是,需要的数据通常是多个表联合查询的结果,我们的索引是如何建立?

使用视图,对多表建立视图,在视图上面创建索引?

还是单表索引,只是把联合查询化解,在lucene的索引中使用多次查询,找到目标,在数据库查询?

和数据使用的时候 ,索引到底是和数据库数据相关联的,还是和结果集相关联的?

写测试程序发现,应该是索引在数据结果集上面的。

测试如下:

t_user 表

t_user_teacher 表

t_teacher 表

package lucene_demo05;

import java.io.IOException;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import org.apache.lucene.analysis.Analyzer;

import org.apache.lucene.document.Document;

import org.apache.lucene.document.Field;

import org.apache.lucene.document.TextField;

import org.apache.lucene.index.CorruptIndexException;

import org.apache.lucene.index.DirectoryReader;

import org.apache.lucene.index.IndexWriter;

import org.apache.lucene.index.IndexWriterConfig;

import org.apache.lucene.index.IndexWriterConfig.OpenMode;

import org.apache.lucene.queryparser.classic.ParseException;

import org.apache.lucene.queryparser.classic.QueryParser;

import org.apache.lucene.search.IndexSearcher;

import org.apache.lucene.search.Query;

import org.apache.lucene.search.ScoreDoc;

import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;

import org.apache.lucene.store.Directory;

import org.apache.lucene.store.RAMDirectory;

import org.apache.lucene.util.Version;

import org.wltea.analyzer.lucene.IKAnalyzer;

/**

*

* Lucene与数据库结合使用

*

* @author YipFun

*/

public class LuceneDemo06

{

private static final String driverClassName = "com.mysql.jdbc.Driver";

private static final String url = "jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8";

private static final String username = "****";

private static final String password = "****";

private static final Version version = Version.LUCENE_4_9;

private Directory directory = null;

private DirectoryReader ireader = null;

private IndexWriter iwriter = null;

private IKAnalyzer analyzer;

private Connection conn;

public LuceneDemo06()

{

directory = new RAMDirectory();

}

public IndexSearcher getSearcher()

{

try

{

if (ireader == null)

{

ireader = DirectoryReader.open(directory);

} else

{

DirectoryReader tr = DirectoryReader.openIfChanged(ireader);

if (tr != null)

{

ireader.close();

ireader = tr;

}

}

return new IndexSearcher(ireader);

} catch (CorruptIndexException e)

{

e.printStackTrace();

} catch (IOException e)

{

e.printStackTrace();

}

return null;

}

public Connection getConnection()

{

if (this.conn == null)

{

try

{

Class.forName(driverClassName);

conn = DriverManager.getConnection(url, username, password);

} catch (ClassNotFoundException e)

{

e.printStackTrace();

} catch (SQLException e)

{

e.printStackTrace();

}

}

return conn;

}

private IKAnalyzer getAnalyzer()

{

if (analyzer == null)

{

return new IKAnalyzer();

} else

{

return analyzer;

}

}

public void createIndex()

{

Connection conn = getConnection();

ResultSet rs = null;

PreparedStatement pstmt = null;

if (conn == null)

{

System.out.println("get the connection error...");

return;

}

String sql = "select " + "u.id as uid," + "u.name as uname," + "u.psd as upsd," + "u.email as uemail," + "u.tel as utel," + "t.id as tid,"

+ "t.name as tname " + "from t_user u , t_user_teacher ut ,t_teacher t " + "where u.id=ut.u_id and ut.t_id= t.id ";

try

{

pstmt = conn.prepareStatement(sql);

rs = pstmt.executeQuery();

IndexWriterConfig iwConfig = new IndexWriterConfig(version, getAnalyzer());

iwConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);

iwriter = new IndexWriter(directory, iwConfig);

while (rs.next())

{

int id = rs.getInt("uid");

String name = rs.getString("uname");

String psd = rs.getString("upsd");

int tid = rs.getInt("tid");

String tname = rs.getString("tname");

Document doc = new Document();

doc.add(new TextField("uid", id + "", Field.Store.YES));

doc.add(new TextField("uname", name + "", Field.Store.YES));

doc.add(new TextField("upsd", psd + "", Field.Store.YES));

doc.add(new TextField("tid", tid + "", Field.Store.YES));

doc.add(new TextField("tname", tname + "", Field.Store.YES));

iwriter.addDocument(doc);

}

} catch (SQLException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

} finally

{

try

{

if (iwriter != null)

iwriter.close();

rs.close();

pstmt.close();

if (!conn.isClosed())

{

conn.close();

}

} catch (IOException e)

{

e.printStackTrace();

} catch (SQLException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

public void searchByTerm(String field, String keyword, int num) throws InvalidTokenOffsetsException

{

IndexSearcher isearcher = getSearcher();

Analyzer analyzer = getAnalyzer();

// 使用QueryParser查询分析器构造Query对象

QueryParser qp = new QueryParser(version, field, analyzer);

// 这句所起效果?

qp.setDefaultOperator(QueryParser.OR_OPERATOR);

try

{

Query query = qp.parse(keyword);

ScoreDoc[] hits;

// 注意searcher的几个方法

hits = isearcher.search(query, null, num).scoreDocs;

System.out.println("the ids is =");

for (int i = 0; i < hits.length; i++)

{

Document doc = isearcher.doc(hits[i].doc);

System.out.print(doc.get("uid") + " ");

}

} catch (IOException e)

{

e.printStackTrace();

} catch (ParseException e)

{

e.printStackTrace();

}

}

public static void main(String[] args) throws InvalidTokenOffsetsException

{

LuceneDemo06 ld = new LuceneDemo06();

ld.createIndex();

ld.searchByTerm("tname", "aaa", 100);

}

}

搜索教师为aaa的学生的Id

结果:

加载扩展词典:ext.dic

加载扩展停止词典:stopword.dic

the ids is = 1 2

mysql lucene 结合_Lucene基础(四)-- 结合数据库使用相关推荐

  1. mysql 连接 分组_MySQL 基础 (四) 分组查询及连接查询

    MySQL 基础 (四) 分组查询及连接查询 MySQL 基础(四) 进阶 5 分组查询 语法: SELECT 分组函数, 列(要求出现在 group by 的后面) FROM 表 [where 筛选 ...

  2. 【数据库基础】01_数据库概述与MySQL语法基础

    1. 数据库应用 1.1 概述 1.1.1 什么是数据库 简而言之,就是存储数据,管理数据的仓库. 数据库的好处 持久化数据到本地. 可以实现结构化查询,方便管理. DB:数据库(database): ...

  3. MYSQL的地理信息数据库_国家基础地理信息系统数据库

    地理信息系统论坛:最专业GIS中文互动门户 国家基础地理信息系统数据库 [日期:2008-02-29] 来源:国家测绘局  作者: [字体:大 中 小] 国家基础地理信息系统是以形成数字信息服务的产业 ...

  4. MySql基础篇---001 数据库概述与MySQL安装篇:概述,表和类对应关系,表关系、数据库卸载,下载,安装,配置,启动,登录,演示,图形化工具,目录结构,常见问题

    第01章_数据库概述 讲师:尚硅谷-宋红康(江湖人称:康师傅) 官网:http://www.atguigu.com 1. 为什么要使用数据库 持久化(persistence):把数据保存到可掉电式存储 ...

  5. Java各类技能知识点学习链接大全:四、数据库Sql,Mysql相关

    以下内容大多是学习链接,他人整理,个人收藏以便复习,同时归纳分享出来(如有不妥,原作者可随时联系本人删除,感谢!) 四.数据库Sql,Mysql相关 1.MySQL中锁详解(行锁.表锁.页锁.悲观锁. ...

  6. mysql数据库重命名php_mysql基础:删除数据库,删除表,重命名表_MySQL

    bitsCN.com mysql基础:删除数据库,删除表,重命名表 ============删除数据库============= DROP DATABASE用于取消数据库中的所用表格和取消数据库.使用 ...

  7. MySQL / 自带的四个数据库介绍

    终端登录 mysql 数据库,显示全部数据库(或者直接用客户端工具展示),如下: 四个系统自带库为:information_schema.mysql.performance_schema.sys . ...

  8. 零基础带你学习MySQL—数学函数(十四)

    零基础带你学习MySQL-数学函数(十四)

  9. MySQL | MySQL 数据库系统(四)- 数据库的备份与恢复

    前言 大家在日常的工作中,备份数据其实是信息安全管理重要的工作之一.那么,我们在这篇文章中将介绍一下数据库的备份与恢复.MySQL 数据库的备份同时有多种方式.第一:直接打包数据库文件夹/etc/lo ...

最新文章

  1. wpf 绑定数据无法更新ui控件可能存在的问题
  2. 2014年年度工作总结--IT狂人实录
  3. springboot mybatis 项目框架源码 shiro 集成代码生成器 ehcache缓存
  4. js setTimeout 传递带参数的函数的2种方式
  5. 可申请试用!GN4系列GPU云服务器重磅来袭
  6. python读取.nii.gz文件并展示医学图片
  7. DataGrid单击行时改变颜色
  8. std string与线程安全,是std :: regex线程安全吗?
  9. Hadoop配置项整理(hdfs-site.xml)
  10. mysql locked myisam_MySql 事务 隔离级别 知识点
  11. 【源码小记】jQueryの事件绑定
  12. 利用SAP 0day,四分钟内黑掉华尔街
  13. android go 测试,从Gradle在Android中进行JUnit测试:“程序包android.test不存在”
  14. 树莓派4B点亮LED小灯
  15. 明尼苏达量表结果分析_MMPI明尼苏达多项人格心理测试量表结果分析
  16. Unity3D U3D安装教程
  17. 全球上线!ABB中国涡轮增压器分拆 – 数据清理阶段完成
  18. reshape2揉数据
  19. 深入理解JVM03--判断对象是否存活(引用计数算法、可达性分析算法,最终判定),Eclipse设置GC日志输出,引用
  20. 淘宝/天猫盗图投诉之提交盗图申诉材料时,图片过大,如何缩小呢?

热门文章

  1. HackTheBox——Beep
  2. PID 控制保姆级培训教程下-全国大学生电子设计大赛赛前必备
  3. Structural Deep Embedding for Hyper-Networks
  4. Hexo+Buttterly+Github Pages构建个人博客
  5. 网页 变黑白网页(灰色)
  6. JS流程控制语句 反反复复(while循环) 和for循环有相同功能的还有while循环, while循环重复执行一段代码,直到某个条件不再满足。...
  7. 【题解】[CQOI2009] 循环赛
  8. 基于VGG的猫狗识别
  9. fatal: could not create work tree dir ‘xxx’: Permission denied解决办法
  10. 如何高效的使用搜索引擎