当前位置:Gxlcms > 数据库问题 > Lucene索引并检索数据库

Lucene索引并检索数据库

时间:2021-07-01 10:21:17 帮助过:26人阅读

    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

人气教程排行