数据库本就具有检索功能,使用标准的Sql语句很容易从一个表中获取指定的内容。
另一方面,越来越多的应用系统要求文本的模糊查找,各大数据库厂商提供了各种全文检索的索引功能,来支持全文检索,但是效果一般,尤其是在大数据量的情况下,对服务器和系统的设置都要求专业人士来维护。
另一方面企业级检索、本地检索的发展,要求把不同的数据源通过同一的方式检索出来,实现异构信息的整合,把各种非结构化数据、半结构化数据存放到数据库中是无法进行操作的。只能把数据库的数据也通过搜索引擎和全文检索系统索引起来。
可以使用Lucene索引数据库,实现异构信息的整合检索,大致步骤为:
- 创建一个数据库表,导入或添加记录
- 通过JDBC访问数据库记录,建立数据流
- 数据记录作为文档,记录里的字段作为域添加到文档中
- 创建索引,循环添加文档,直至数据库表记录结束
public static void main(String[] args) {
// int nums = indexBuilder(new File("Dest_Index_Path"), new File("Test_File_Path"));
// System.out.println("doc counts is : " + nums);
getDbConnection("dbname", "user", "password");
record = getResultSet("sql");
indexDbBuilder(new File("xxx"));
}
private static Connection conn = null;
private static Statement statmt = null;
private static ResultSet record = null;
/**
* 创建数据记录的RAM内存索引,生成并添加新文档,合并到本地磁盘索引中去。
* @param indexPath 指定索引目录
*/
public static void indexDbBuilder(File indexPath) {
try {
Analyzer analyzer = new StandardAnalyzer();//文本分析器
IndexWriterConfig conf = new IndexWriterConfig(Version.LATEST, analyzer);
conf.setUseCompoundFile(true);//采用多文件索引结构,默认为复合索引
//文档添加到内存索引
Directory ramDir = new RAMDirectory();
IndexWriter ramWriter = new IndexWriter(ramDir, conf);
//添加内存索引到磁盘索引
Directory fsdDir = FSDirectory.open(indexPath);
IndexWriter fsdWriter = new IndexWriter(fsdDir, conf);
while (record.next()) {
Document document = new Document();
//TextField和StringField的不同是TextField既索引又分词
Field fieldId = new IntField("ID", record.getInt("ID"), Store.YES);
Field fieldName = new StringField("name", record.getString("name"), Store.YES);
Field fieldInfo = new TextField("info", record.getString("info"), Store.NO);
document.add(fieldId);
document.add(fieldName);
document.add(fieldInfo);
ramWriter.addDocument(document);
ramWriter.close();
fsdWriter.addIndexes(new Directory[] {ramDir});//添加内存索引到磁盘索引
}
fsdWriter.forceMerge(5);//优化压缩段,执行优化的方法,参数表示优化称几段索引
fsdWriter.close();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
private static ResultSet getResultSet(String sql) {
ResultSet rs = null;
try {
statmt = conn.createStatement();
rs = statmt.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
private static void getDbConnection(String dbname, String user, String password) {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager
.getConnection("jdbc:mysql://localhost:3306/xxx?user=xxx&password=xxx");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}