问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何用java的lucene对数据库进行全文检索

发布网友 发布时间:2022-04-07 22:28

我来回答

2个回答

懂视网 时间:2022-04-08 02:49

    Lucene是一个开源的全文检索引擎工具包,它提供了完整的索引引擎、查询引擎和部分文本分析引擎。Lucene为软件开发人员提供了一套简单易用的检索引擎开发工具包,以便在系统中实现全文检索功能,或者以Lucene为基础建立一套完整的全文检索引擎。      全文搜索引擎的工作原理:扫描问答库中的每一条记录并分词建立索引,索引记录了词在每一条问答记录中出现的次数和位置,当收到用户的问题时,也会对问题进行分词,然后从索引中找出包含这些词的所有回答记录,再分别计算这些问答记录与用户问题的相似度,找出相似度最高的一条回答记录返回给用户。     Lucene的优点:索引文件格式独立于应用平台、高效的索引引擎、强大的查询引擎、易扩展。

2.Lucene索引和检索原理

    Lucene能够对任何数据做索引和检索,像txt、word、pdf、数据库等格式的数据源,我们都可以通过其他工具或编程方式将这些格式的数据读取出来,转化为文本形式的数据,这样就能使用Lucene对这些文本数据建立索引以及做检索。

3.Lucene索引和检索数据库

    1.创建JDBC获取Connection工具类 
package com.tgb.org;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * JDBC获取Connection工具类 
 * @author quwenzhe
 *
 */
public class JdbcUtil {
	private static Connection conn = null;
	private static final String URL = "jdbc:mysql://localhost:3306/lucene";
	private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
	private static final String USER_NAME = "root";
	private static final String PASSWORD = "root";

	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;
	}
}
          2.创建JavaBean类
package com.tgb.org;

public class UserInfo {
	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;
	}
}
             3.对数据库信息创建索引并对索引进行检索
package com.tgb.org;

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.TextField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
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.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;

public class SearchLogic {
	private static Connection conn = null;
	private static Statement stmt = null;
	private static ResultSet rs = null;
	// 索引保存目录
	private String indexDir = "D:\lucence\index2";
	private static IndexSearcher searcher = null;
	//创建分词器
	private static Analyzer analyzer = new IKAnalyzer(true);

	/**
	 * 获取数据库数据
	 * @param queryStr 需要检索的关键字
	 * @return
	 * @throws Exception
	 */
	public List<UserInfo> getResult(String queryStr) throws Exception {
		List<UserInfo> result = null;
		conn = JdbcUtil.getConnection();
		if (conn == null) {
			throw new Exception("数据库连接失败!");
		}
		String sql = "select id, username from t_user";
		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 访问数据库返回的ResultSet
	 * @throws Exception
	 */
	private void createIndex(ResultSet rs) throws Exception {
		// 创建或打开索引
		Directory directory = FSDirectory.open(new File(indexDir));
		// 创建IndexWriter
		IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_46,
				analyzer);
		IndexWriter indexWriter = new IndexWriter(directory, conf);
		// 遍历ResultSet创建索引
		while (rs.next()) {
			// 创建document并添加field
			Document doc = new Document();
			doc.add(new TextField("id", rs.getString("id"), Field.Store.YES));
			doc.add(new TextField("username", rs.getString("username"),
					Field.Store.YES));
			// 将doc添加到索引中
			indexWriter.addDocument(doc);
		}
		indexWriter.commit();
		indexWriter.close();
		directory.close();
	}

	/**
	 * 检索索引
	 * @param queryStr 需要检索的关键字
	 * @return
	 * @throws Exception
	 */
	private TopDocs search(String queryStr) throws Exception {
		//创建或打开索引目录
		Directory directory = FSDirectory.open(new File(indexDir));
		IndexReader reader = IndexReader.open(directory);
		if (searcher == null) {
			searcher = new IndexSearcher(reader);
		}
		//使用查询解析器创建Query
		QueryParser parser = new QueryParser(Version.LUCENE_46, "username",
				analyzer);
		Query query = parser.parse(queryStr);
		//从索引中搜索得到排名前10的文档
		TopDocs topDocs = searcher.search(query, 10);
		return topDocs;
	}

	/**
	 * 将检索结果添加到List中
	 * @param scoreDocs
	 * @return
	 * @throws Exception
	 */
	private List<UserInfo> addHits2List(ScoreDoc[] scoreDocs) throws Exception {
		List<UserInfo> listBean = new ArrayList<UserInfo>();
		UserInfo bean = null;
		for (int i = 0; i < scoreDocs.length; i++) {
			int docId = scoreDocs[i].doc;
			Document doc = searcher.doc(docId);
			bean = new UserInfo();
			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<UserInfo> result = logic.getResult("屈文哲");
			int i = 0;
			for (UserInfo 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());
		}
	}
}
   项目依赖的jar:
   技术分享
   看完上述代码我们可以发现,Lucene对访问数据库的返回值ResultSet建立索引,然后通过对索引进行检索,检索出符合条件的数据,从而提高对数据库的查询效率。

Lucene索引并检索数据库

标签:lucene

热心网友 时间:2022-04-07 23:57

lucene是一个公用的全文索引组件,它的目标是把各种各样格式的数据转化成lucene特有的索引文件格式,这样才能通过lucene的高速检索机制进行全文检索。

你的数据来源可以是关系数据库,可以是word、execl、txt文档,可以是html网页,对于这些数据源,你必须将它们内部的数据读取出来,并封装成lucene的document实例,之后让lucene帮你构建索引。

举个例子:你的有一个用户数据库,里面存储了几十万的用户信息,你现在要对这个数据库进行全文索引,那么你要做的事情是:

1.写一段传统的JDBC程序,讲每条的用户信息从数据库读取出来
2.针对每条用户记录,建立一个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的索引库
3.编写对索引库的搜索程序(看lucene文档),通过对lucene的索引库的查找,你可以快速找到对应记录的ID
4.通过ID到数据库中查找相关记录

上面阐述了lucene的大体用法,不知道是不是说的很清楚。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
绩效工资从工资里扣合法吗 无人机电机轴的主要功能有哪些? 闽侯南通多久发展 南通哪个位置最有潜力 南通未来的机遇有哪些 江苏南通的发展前景怎么样 南通这座城市未来发展前景怎样 我女儿阳历08年01月08日出生,{农历07年腊月初一}请高人帮忙改个名字... 我女儿是2012年1月10日10:35分出生的五行缺什么,取什么名字好 这种图片效果怎么做出来的,不是纯白板,仔细看有一个个均匀分布的小圆点... 我的微信发了几张黄色小图片。大约七天才能解封? 删除微信好友显示黄色小字? 微信接语音和发语音为什么有个黄色小点点苹果手机? 社会保险职工增减表的线上盖章怎么盖 淋巴癌可以治愈吗??大概多少钱?? 浙里办生育津贴线上签章需要盖章吗 尉氏农商银行副行长都有谁 恶性肿瘤胸椎转移的诊断与治疗鼻咽癌 汴捷贷营销关系绑定失败 十万火急!慢性肾衰的晚期肾盂癌求救 应届生成绩单盖章能线上盖章吗? 泰欣生怎么使用,一个疗程多长时间? 泰欣生和国外产品相比,有价格优势吗? 泰欣生治疗费用如何? 线上办公,企业要用电子印章,怎么才能有法律效力? 江铃特顺国六第二次保养保养里程调到多少? 怎样按风险排序来购买银行理财产品 理财产品的风险排序是怎样的? 有没有一个将多页PDF文件打印到一页的软件 PDF批量打印软件 2015麦玲玲12生肖运程属牛三月份 12生肖2010年运势牛 宋茜与圭贤他俩咋的了? 2013年生肖每月运程,2013年运程麦玲玲预测的。 曺圭贤宋茜到底发生了什么事情 麦玲玲12生肖运程化解配饰在哪儿买 梦见女人给俺送背包和书笔 圭贤和宋茜 明牙是否关系到一个人的财运和婚姻方面的问题呢? 圭贤和宋茜是什么关系? 2010年十二生肖运势 女人梦见情人送书给闺蜜? 圭贤和宋茜什么关系 为什么圭贤微博只关注宋茜一个女生 东莞民间借贷网,哪个好? 宋茜圭贤为什么传绯闻 梦见女朋友情人节送书给自己是什么意思,还是本有关革命历史的书! 有关广东东莞地区高利息民间借贷的问题。 宋茜和圭贤关系很好吗~怎么变好的~ 有谁和宋茜关系很好 怎么锻炼两肋的肌肉