- 浏览: 208254 次
- 性别:
- 来自: 福建省
文章分类
最新评论
-
c929833623:
...
Mysql JDBC驱动源码分析(Statement,ResultSet的创建)四 -
pythonlord:
顶 很有帮助,感谢楼主,好人一生平安
Mysql JDBC驱动源码分析(加载驱动)一 -
kiaonly:
代码有错误,我戳。
解释器模式(Interpreter)---java与模式(例子) -
wyzxzws:
小鸟学习了!
JAVA编码问题记录 -
xiaotao.2010:
写的不错! 弱弱说一句 建议使用URL二次转码, 这样可以避免 ...
JAVA编码问题记录
一,对Lucene的知识进行介绍http://lym6520.iteye.com/category/82172
二,以下对最近所使用的Lucene,进行总结下:
为了使Lucene创建的索引文件,能够及时与数据库中同步,使用了quartz进行任务调度可查看
http://wuquanyin1011.iteye.com/admin/blogs/745382
下面是一个任务调度执行Lucene创建索引
以下给个大概重建索引,是使用了建模端配置创建索引
package com.fdauto.bws.business.module.lucene.index.job; import java.io.File; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import com.fdauto.bws.business.datasource.DataSource; import com.fdauto.bws.business.datasource.DataSourceHelper; import com.fdauto.bws.common.logger.SystemLogsHelper; import com.fdauto.bws.service.config.BWSConfigHelper; /** * 任务调度定时创建索引 * * @author wu_quanyin(09817) * @version 1.0 * @date 2010-7-16 上午10:54:01 */ public class LuceneIndexJob implements Job { private String indexParentDir = BWSConfigHelper.getBWSConfig() .getProperties().getProperty("indexDir"); @SuppressWarnings("unchecked") public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); String sql = jobDataMap.getString("sql"); String indexDir = jobDataMap.getString("indexFileDir"); String dataSourceName = jobDataMap.getString("dataSource"); if (sql == null || indexDir == null || dataSourceName == null) { SystemLogsHelper.error("索引数据集中:sql语句-->" + sql + "\n" + "索引文件:-->" + indexDir + "\n" + "数据源-->" + dataSourceName + "都不能为空!"); } // 指定父目录 indexDir = indexParentDir + "/" + indexDir; File indexFile = new File(indexDir); if (!indexFile.exists()) { indexFile.mkdirs(); } // 获取字段索引策略 ColumnIndexStrategy columnIndexStrategy = new ColumnIndexStrategy(); // 删除sql字段后,,对查询字段进行处理 jobDataMap.remove("sql"); jobDataMap.remove("dataSource"); jobDataMap.remove("indexFileDir"); Set<Map.Entry<String, String>> columnSet = jobDataMap.entrySet(); for (Iterator<Map.Entry<String, String>> iter = columnSet.iterator(); iter .hasNext();) { Map.Entry<String, String> columnEntry = iter.next(); String columnKey = columnEntry.getKey(); String columnValue = columnEntry.getValue(); String[] strategys = columnValue.split(","); if (strategys.length == 3) { columnIndexStrategy.add(columnKey.toUpperCase(), strategys[0] .toUpperCase(), strategys[1].toUpperCase(), strategys[2], 1); } else if (strategys.length == 4) { columnIndexStrategy.add(columnKey.toUpperCase(), strategys[0] .toUpperCase(), strategys[1].toUpperCase(), strategys[2], Integer.parseInt(strategys[3])); } } IndexWriter indexWriter = null; Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { DataSource dataSource = DataSourceHelper .getDataSource(dataSourceName); conn = dataSource.getConnection(); LuceneIndex luceneIndex = LuceneIndexFactory.getLuceneIndex(); indexWriter = luceneIndex.getIndexWriter(indexDir, true); ps = conn.prepareStatement(sql); rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); while (rs.next()) { Document doc = new Document(); for (int i = 1; i <= rsmd.getColumnCount(); i++) { String columnName = rsmd.getColumnName(i).toUpperCase(); if (!jobDataMap.containsKey(columnName)) { continue; } String columnValue = SQLDataType.requireValueByColumnType( rs, rsmd.getColumnType(i), i, false); if (columnValue == null || columnValue.trim().length() == 0) { continue; } if ("HTML".equalsIgnoreCase(columnIndexStrategy .getFieldContentType(columnName)) && columnIndexStrategy.getFieldIndex(columnName) != Index.NO) { columnValue = filterHtmlLable(columnValue); } // ----判断如果是检索不分词时,,值转换为小写 if (columnIndexStrategy.getFieldIndex(columnName) == Index.NOT_ANALYZED) { columnValue = columnValue.toLowerCase(); } Field f = new Field( columnName,// 名称 columnValue,// 值 // 对每一个字段执行不同的索引策略 columnIndexStrategy.getFieldStore(columnName), columnIndexStrategy.getFieldIndex(columnName)); int boost = columnIndexStrategy.getBoost(columnName); if (boost > 0) f.setBoost(boost); doc.add(f); } indexWriter.addDocument(doc); } //将索引的信息打印到控制台上。 if(SystemLogsHelper.isDebugger()){ System.out.println("index infos--------------------->"); indexWriter.setInfoStream(System.out); } indexWriter.optimize(); indexWriter.commit(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (indexWriter != null) indexWriter.close(); } catch (Exception e) { SystemLogsHelper.trace("Could not close Lucene IndexWriter", e); } try { if (rs != null) rs.close(); } catch (Exception e) { SystemLogsHelper.trace("Could not close JDBC ResultSet", e); } try { if (ps != null) ps.close(); } catch (Exception e) { SystemLogsHelper.trace("Could not close JDBC Statement", e); } try { if (conn != null) conn.close(); } catch (Exception e) { SystemLogsHelper.trace("Could not close JDBC Connection", e); } } } /** * 对有字段标签先过滤再全文检索 * * @param field * 含有html标签的字段 * @return */ private static String filterHtmlLable(String field) { StringBuffer result = new StringBuffer(); try { String body = field; Parser nodesParser = Parser.createParser(body, "UTF-8"); NodeFilter textFilter = new NodeClassFilter(TextNode.class); NodeList nodeList = nodesParser.parse(textFilter); Node[] nodes = nodeList.toNodeArray(); for (int i = 0; i < nodes.length; i++) { Node nextNode = (Node) nodes[i]; String content = ""; if (nextNode instanceof TextNode) { TextNode textnode = (TextNode) nextNode; content = textnode.getText(); } result.append(" "); result.append(content); } } catch (Exception e) { e.printStackTrace(); } field = result.toString(); if (StringHelper.isEmpty(field)) return field; // field = field.replaceAll("</p(?:\\s*)>(?:\\s*)<p(?:\\s*)>", "\n\n"); // field = field.replaceAll("<br(?:\\s*)/>", "\n"); // field = field.replaceAll("\"", "''"); field = field.replaceAll("<[^>]+>?", ""); return field; } public static void main(String[] args) { System.out .println(LuceneIndexJob .filterHtmlLable("<p class=MsoNormal style=\"MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 28pt; TEXT-ALIGN: left; mso-layout-grid-align: none\" align=left><span style=\"FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'\">在主仓库内备货,按库存金额的</span><span lang=EN-US style=\"FONT-SIZE: 9pt\"><font face=\"Times New Roman\">0.1</font></span><span style=\"FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'\">‰每天计算占库费用,在其他仓库则需按仓库库存金额的</span><span lang=EN-US style=\"FONT-SIZE: 9pt\"><font face=\"Times New Roman\">0.12</font></span><span style=\"FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'\">‰计算占库费。</span><span lang=EN-US style=\"FONT-SIZE: 9pt\"><?xml:namespace prefix = o ns = \"urn:schemas-microsoft-com:office:office\" /></span></p>")); } }
数据库类型判断:
public class SQLDataType { public static String requireValueByColumnType(ResultSet rs, int columnType, int columnIndex) throws SQLException { String returnValue = ""; switch (columnType) { case Types.BOOLEAN: returnValue = rs.getBoolean(columnIndex) ? "TRUE" : "FALSE"; break; case Types.TIMESTAMP: returnValue = rs.getTimestamp(columnIndex).toString(); break; case Types.BLOB: Blob b = rs.getBlob(columnIndex); //maybe affect to return result byte[] blobs = b.getBytes(0, (int) b.length()); returnValue = new String(Base64.decodeBase64(blobs)); break; case Types.CLOB: returnValue = new String(Base64.decodeBase64(rs.getString( columnIndex).getBytes())); break; default: returnValue = rs.getString(columnIndex); } return returnValue; } }
Lucene进行查询:
public class DatabaseSearch extends SearchSupport { private static final String __SEARCHTEXT = "__q"; // "="(默认)为精确匹配,"like"为不精确匹配 private String operator = "like"; // 用于加高亮时的显示 private Query useHighLightQuery; @Override public TopDocs execSearch(int pageSize, int pageIndex, Parameters ps, LuceneStore luceneStore) throws Exception { // 用来判断唯一字段 String uniqueField = ""; // 默认为or的策略 String searchType = "SEARCH_OR"; FieldSet fieldSet = luceneStore.getFields(); int fieldSize = fieldSet.fieldSize(); if (fieldSet.getField("luceneScore") != null) fieldSize = fieldSize - 1; String[] indexFields = new String[fieldSize]; BooleanClause.Occur[] clauses = new BooleanClause.Occur[fieldSize]; for (int i = 0; i < fieldSet.fieldSize(); i++) { LuceneField luceneField = (LuceneField) fieldSet.getField(i); if (luceneField.getName().equalsIgnoreCase("LuceneScore")) continue; indexFields[i] = luceneField.getName(); searchType = luceneField.getSearchType(); clauses[i] = ColumnSearchStrategy.getClause(searchType .toUpperCase()); // 取第一个标为唯一的字段 if (luceneField.isUnique() && uniqueField.equals("")) { uniqueField = indexFields[i]; } } ArrayList<MatchRule> matchRules = luceneStore.getMatchRules(); DefaultExprResolver der = new DefaultExprResolver(); for (Iterator<MatchRule> itr = matchRules.iterator(); itr.hasNext();) { MatchRule matchRule = itr.next(); if (matchRule instanceof SQLMatchRule) { SQLMatchRule sqlMatchRule = (SQLMatchRule) matchRule; if (__SEARCHTEXT.equalsIgnoreCase(sqlMatchRule.getName())) { this.operator = sqlMatchRule.getOperator().trim(); } if (ps.exists(sqlMatchRule.getName())) continue; if (StringHelper.isNotEmpty(ps .getString(sqlMatchRule.getName()))) continue; if (luceneStore.getFields().getField(sqlMatchRule.getName()) == null) continue; // if (StringHelper.isEmpty(sqlMatchRule.getRightSide())) // continue; ps.setDataType(sqlMatchRule.getName(), sqlMatchRule .getDataType()); ps.setValue(sqlMatchRule.getName(), QLExpressHelper.getRunner() .execute( (String) der.evaluate(null, sqlMatchRule .getRightSide()), null, null, false, false)); } } boolean addQuery = false; Query query; query = new BooleanQuery(); for (int i = 0, ilen = ps.count(); i < ilen; ++i) { String name = ps.indexToName(i); if (name.equalsIgnoreCase(__SEARCHTEXT)) continue; if (luceneStore.getFields().getField(name) == null) continue; String value = ps.getString(i); if (StringHelper.isEmpty(value)) continue; // QueryParser qp = new QueryParser(Version.LUCENE_30, name, this // .getAnalyzer()); // Query q1 = qp.parse(value); Query q1 = BWSQueryParser.parseMultiField(new String[] { name }, value, new BooleanClause.Occur[] { Occur.SHOULD }, false); if (q1 != null) { ((BooleanQuery) query).add(q1, BooleanClause.Occur.MUST); addQuery = true; } } // 要查询的值 String queryValue = ps.getString(__SEARCHTEXT); if (!StringHelper.isEmpty(queryValue)) { // 是否精确查找(是否对传过来的值再进行分词查找) boolean exactMatch = false; if (!operator.equalsIgnoreCase("=")) {// 不精确查找"或"的关系 exactMatch = false; StringBuffer buffers = new StringBuffer(); buffers.append(queryValue); buffers.append(" "); buffers.append("\""); buffers.append(queryValue.replaceAll("[\\s| ]+", "-")); buffers.append("\""); queryValue = buffers.toString();// 增加权重 } else {// 精确查找"且"的关系 exactMatch = true; } Query q2 = BWSQueryParser.parseMultiField(indexFields, queryValue, clauses, exactMatch); ((BooleanQuery) query).add(q2, BooleanClause.Occur.MUST); // Query q2 = IKQueryParser.parseMultiField(indexFields, queryValue, // clauses); addQuery = true; } if (!addQuery) throw new NoKeywordsException("查询关键字不能为空!"); int topSize = 100; if (pageSize > 0) { if (pageIndex > 0) { topSize = pageSize * pageIndex; } else topSize = pageSize; } Sort sort = null; ArrayList<SortField> sortFields = new ArrayList<SortField>(); for (Iterator<SortRule> itr = luceneStore.getSortRules().iterator(); itr .hasNext();) { SortRule sortRule = itr.next(); Field f = luceneStore.getFields().getField(sortRule.getFieldName()); if (f != null) { sortFields.add(new SortField(f.getName(), SortField.STRING, sortRule.isDescent())); } } if (sortFields.size() > 0) { SortField[] sortArray = new SortField[sortFields.size()]; sort = new Sort(sortFields.toArray(sortArray)); } // 因为下面的过虑重复,扩展的query,用于高度时会有问题,故在此提取出来 setUseHighLightQuery((Query) query.clone()); if (StringHelper.isNotEmpty(uniqueField)) { // 以下的filter,与query要配合使用才能执行 DuplicateExtendFilter filter = new DuplicateExtendFilter( uniqueField); query = new DuplicateQuery(query, filter); } if (sort == null) return getIndexSearcher().search(query, null, topSize); else return getIndexSearcher().search(query, null, topSize, sort); } public Query getUseHighLightQuery() { return useHighLightQuery; } public void setUseHighLightQuery(Query useHighLightQuery) { this.useHighLightQuery = useHighLightQuery; } }
根据以上两个类,与公司建模端结合,建模端所配置的参数不同,创建不同的工作,执行不同的索引........
发表评论
-
Solr研究
2012-03-26 10:14 2330一,概述 17173搜索是一套对站内各个系统的信 ... -
Lucene---全文检索(处理一对多去重问题 )
2011-01-13 16:15 5909在处理如"问答"功能时,以答进行搜索,这时假就会出现去重问题- ... -
Lucene---全文检索(问题分析)
2010-12-03 15:46 5898创建索引时处理: 一,是否要被分词 1,Fie ... -
Lucene---全文检索(文档pdf/txt/office/html)
2010-11-01 11:08 3091一,最近做了一些使用lucene对文档的一些搜索 主要使用 ...
相关推荐
《最新全文检索 Lucene-5.2.1 入门经典实例》 Lucene是一个开源的全文检索库,由Apache软件基金会开发,广泛应用于各种信息检索系统。在5.2.1版本中,Lucene提供了更为高效和强大的搜索功能,为开发者提供了构建...
使用compass+lucene实现简单的全文检索功能 里面整合了spring2.5、hibernate3.2、struts2.0,是对数据库进行全文检索的一个非常好的demo的所有jar包组合! 对研究基于数据库检索的java开源搜索引擎的朋友有很大的...
作为Java实现的全文检索引擎,Lucene提供了一套高度可扩展的API,支持索引和搜索大量文本数据。在“lucene-core-2.4.0.jar”这个版本中,Lucene已经相当成熟,可以满足各种复杂的搜索需求。 二、核心组件 1. 文档...
这个“lucene-project.zip”文件包含了学习Lucene全文检索程序的相关资源,是针对初学者的一个入门教程。 **Lucene的核心概念** 1. **文档(Document)**:在Lucene中,文档是信息的基本单位,可以看作是数据库中...
Apache Lucene,一个高度可扩展的全文检索库,是Java平台上的开源搜索引擎框架。标题中的“lucene-6.5.0工具包”正是这个强大库的一个特定版本,6.5.0代表着该版本发布时的一系列增强和改进。它不仅提供了基本的搜索...
- 数据库全文检索:增强数据库查询能力,支持模糊匹配和近似搜索。 - 日志分析:快速定位日志中的关键信息。 - 内容推荐系统:根据用户搜索行为进行内容推荐。 四、实战开发 4.1 创建索引: - 使用`...
Lucene是一个高度可扩展的全文检索库,由Apache软件基金会开发并维护。它为开发者提供了在Java应用程序中实现全文索引和搜索功能的强大工具。Lucene 2.1.0版本是其历史中的一个重要里程碑,该版本在性能、稳定性和...
在信息技术领域,搜索引擎的构建是至关重要的一环,而Apache Lucene作为一款开源全文检索库,为开发者提供了强大的文本检索功能。本文将深入探讨Lucene 3.5.0版本,特别是两个核心组件——"lucene-core-3.5.0.jar"和...
Lucene是一个开源的全文检索库,由Apache软件基金会开发并维护。它为Java开发者提供了强大的文本搜索功能,广泛应用于各种需要高效、精确搜索能力的应用场景,如网站、文档管理系统、数据库等。在6.4.0这个版本中,...
《Apache Lucene 6.6.0:全文检索与索引库详解》 Apache Lucene 是一个开源的全文检索库,由Java编写,为开发者提供了强大的文本搜索功能。6.6.0 版本作为官方的最新完整版,集成了众多优化和改进,旨在提供更加...
### 一种基于Lucene检索引擎的全文数据库的研究与实现 #### 1. 引言 随着信息技术的飞速发展和互联网的普及,大量的文本信息被数字化存储,这为信息检索带来了前所未有的挑战和机遇。传统的数据库管理系统(DBMS)...
【新闻发布系统lucene-1.4.1-src】是一个基于Lucene 1.4.1版本的源码项目,主要用于构建新闻信息发布和检索系统。Lucene是Apache软件基金会的一个开源项目,它是一个全文搜索引擎库,提供了强大的文本分析、索引和...
Lucene 是一个高性能、全文本搜索库,被广泛用于构建复杂检索功能。在 Neo4j 中,Lucene 作为默认的内建索引机制,用于加速节点和关系的查找。 这个特定的版本 "1.7.1" 暗示这是一个较早的发布,可能适用于 Neo4j ...
**使用Lucene全文检索数据库** Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发。它是Java编写的,能够帮助开发者在各种应用程序中实现强大的全文检索功能。在这个项目中,我们将探讨如何利用Lucene ...
5. **实战应用**:了解了Lucene的基本概念和工作流程后,我们可以结合实际需求,如网站、数据库或日志文件,构建自己的全文搜索引擎。例如,可以使用Lucene对新闻文章进行索引,然后通过关键词搜索快速定位相关信息...
【全文搜索Lucene & ElasticSearch】是一门关于安装和入门的课程,主要涵盖了全文检索的基本概念,Lucene和ElasticSearch的介绍,以及如何使用Java操作ElasticSearch。全文检索,顾名思义,是对非结构化数据进行搜索...
《Apache Lucene 3.0.0:全文检索与索引库详解》 Apache Lucene 是一个开源的全文检索库,由Java编写,为开发者提供了强大的文本搜索功能。作为一款高度可扩展的搜索引擎框架,Lucene 3.0.0 版本在当时代表着其最新...
作为Java编写的一款开源工具,Lucene被广泛应用于各种需要高效检索功能的系统中,如网站、数据库、文档管理系统等。 在Lucene 4.10.4版本中,我们看到这个压缩包文件"lucene4.10.4.jar"是该版本的核心库,包含了...
基于Lucene的Oracle数据库全文检索 基于Lucene的Oracle数据库全文检索是指使用Lucene搜索引擎来实现Oracle数据库中的全文检索。Lucene是一个开源的全文搜索引擎API,提供了完整的查询引擎和索引引擎,部分文本分析...
1. **全文检索**:Lucene支持对文档中的文本进行分词,创建倒排索引,从而实现快速的全文搜索。 2. **高效性能**:通过优化的数据结构和算法,Lucene能够在大量数据中提供快速的搜索响应时间。 3. **多语言支持**:...