Lucene是一款优秀的全文检索引擎的框架,提供了完整的查询引擎和索引引擎。由于Lucene自带的例子可以正常处理英文文件,但是中文的文件却不能正常处理。网上查了很多资料,很多人都在问这个问题,但是答案却是只字片语,没有针对这个问题提出一个完整的解决办法。经过一番摸索,终于解决了这个问题。关键之处在于读入文件时需要为文件字符流指定编码字符集,并且该字符集需要与文件的编码字符集一致,才能保证根据这些文件创建的索引后,文件的内容能被正确搜索。目前Lucene已经更新到了4.5.1,本文既可以作为最新版本的入门例子,有可以为解决中文文件搜索提供参考。
在D:/work/lucene/example放入测试的文件
D:/work/lucene/index01 为索引文件的存放路径
代码如下(基于Lucene4.5.1编写):
package com.hsdl.lucene; import info.monitorenter.cpdetector.io.ASCIIDetector; import info.monitorenter.cpdetector.io.CodepageDetectorProxy; import info.monitorenter.cpdetector.io.JChardetFacade; import info.monitorenter.cpdetector.io.ParsingDetector; import info.monitorenter.cpdetector.io.UnicodeDetector; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.StringField; import org.apache.lucene.document.TextField; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; 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.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.util.Version; public class LuceneDemo { private static String contentFieldName = "content"; public static void main(String[] args) { Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_45); try { String docPath = "D:/work/lucene/example"; String indexPath = "D:/work/lucene/index01"; //创建索引 createIndex(analyzer, indexPath, docPath); //搜索 search(analyzer, indexPath, "中国"); } catch (CorruptIndexException e) { e.printStackTrace(); } catch (LockObtainFailedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 创建索引 * * @param analyzer * @param indexPath * @param docPath * @throws IOException * @throws CorruptIndexException * @throws LockObtainFailedException */ private static void createIndex(Analyzer analyzer, String indexPath, String docPath) throws IOException, CorruptIndexException, LockObtainFailedException { IndexWriter iwriter; Directory directory = FSDirectory.open(new File(indexPath)); // 配置IndexWriterConfig IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_45, analyzer); iwConfig.setOpenMode(OpenMode.CREATE_OR_APPEND); iwriter = new IndexWriter(directory, iwConfig); File file = new File(docPath); indexDocs(iwriter, file); iwriter.close(); } /** * 搜索 * * @param analyzer * @param indexPath * @param queryStr * @throws CorruptIndexException * @throws IOException * @throws ParseException */ private static void search(Analyzer analyzer, String indexPath, String queryStr) throws CorruptIndexException, IOException, ParseException { Directory directory = FSDirectory.open(new File(indexPath)); // 搜索过程********************************** // 实例化搜索器 IndexReader ireader = DirectoryReader.open(directory); IndexSearcher isearcher = new IndexSearcher(ireader); // 使用QueryParser查询分析器构造Query对象 QueryParser qp = new QueryParser(Version.LUCENE_45, contentFieldName, analyzer); qp.setDefaultOperator(QueryParser.AND_OPERATOR); Query query = qp.parse(queryStr); // 搜索相似度最高的5条记录 TopDocs topDocs = isearcher.search(query, 5); System.out.println("命中:" + topDocs.totalHits); // 输出结果 ScoreDoc[] scoreDocs = topDocs.scoreDocs; System.out.println(scoreDocs.length); for (int i = 0; i < scoreDocs.length; i++) { Document targetDoc = isearcher.doc(scoreDocs[i].doc); System.out.println("内容:" + targetDoc.toString()); System.out.println(targetDoc.get("fileName") + "[" + targetDoc.get("path") + "]"); } } /** * 根据指定存放内容的文件或目录创建索引 * @param iwriter * @param file * @throws IOException */ public static void indexDocs(IndexWriter iwriter, File file) throws IOException { if (file.canRead()) if (file.isDirectory()) { String[] files = file.list(); if (files != null) for (int i = 0; i < files.length; i++) indexDocs(iwriter, new File(file, files[i])); } else { Document doc = null; FileInputStream fis=null; try { doc = new Document(); doc.add(new StringField("ID", "10000", Field.Store.YES)); fis = new FileInputStream(file); System.out.println(getFileCharset(file)); doc.add(new TextField(contentFieldName, new BufferedReader( new InputStreamReader(fis, getFileCharset(file))))); doc.add(new StringField("fileName", file.getName(), Field.Store.YES)); doc.add(new StringField("path", file.getAbsolutePath(), Field.Store.YES)); iwriter.addDocument(doc); } finally { if(fis!=null){ fis.close(); } } } } /** * 获取文件的编码字符集 * @param file * @return */ public static String getFileCharset(File file) { /* * detector是探测器,它把探测任务交给具体的探测实现类的实例完成。 * cpDetector内置了一些常用的探测实现类,这些探测实现类的实例可以通过add方法 加进来,如ParsingDetector、 * JChardetFacade、ASCIIDetector、UnicodeDetector。 * detector按照“谁最先返回非空的探测结果,就以该结果为准”的原则返回探测到的 * 字符集编码。使用需要用到三个第三方JAR包:antlr.jar、chardet.jar和cpdetector.jar * cpDetector是基于统计学原理的,不保证完全正确。 */ CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance(); /* * ParsingDetector可用于检查HTML、XML等文件或字符流的编码,构造方法中的参数用于 * 指示是否显示探测过程的详细信息,为false不显示。 */ detector.add(new ParsingDetector(false)); // ASCIIDetector用于ASCII编码测定 detector.add(ASCIIDetector.getInstance()); // UnicodeDetector用于Unicode家族编码的测定 detector.add(UnicodeDetector.getInstance()); /* * JChardetFacade封装了由Mozilla组织提供的JChardet,它可以完成大多数文件的编码 * 测定。所以,一般有了这个探测器就可满足大多数项目的要求,如果你还不放心,可以 * 再多加几个探测器,比如上面的ASCIIDetector、UnicodeDetector等。需要把这个放在最后添加。 */ detector.add(JChardetFacade.getInstance()); java.nio.charset.Charset charset = null; try { charset = detector.detectCodepage(file.toURI().toURL()); } catch (Exception ex) { ex.printStackTrace(); } if (charset != null){ /* * 如果编码是"windows-1252",将其设置为"GB2312",因为使用的环境为中国, * 一般的文档也是在中文的Windows的环境下创建 */ if(charset.name().equals("windows-1252")){ return "GB2312"; } return charset.name(); } else return null; } }
在运行该例子时除了需要Lucene4.5相关的jar包外,还需要antlr.jar、cpdetector_1.0.8.jar这两个jar包,才能正常编译运行。
在编写这个例子的时候,参考了网上其他朋友的文章及代码,在此一并感谢!
相关推荐
**Lucene5学习之创建索引入门示例** 在IT领域,搜索引擎的开发与优化是一项关键技术,而Apache Lucene作为一款高性能、全文本搜索库,是许多开发者进行文本检索的首选工具。本文将深入探讨如何使用Lucene5来创建一...
在本案例中,我们使用的是 IKAnalyzer,这是一个针对中文的开源分词器,能较好地处理中文分词问题。 4. **索引writer(IndexWriter)**:负责创建或更新索引。我们可以向 IndexWriter 添加文档,然后调用 commit() ...
**Lucene学习入门程序** Lucene是一个开源的全文搜索引擎库,由Apache软件基金会开发并维护。它是Java编写,可以被集成到各种应用中,提供强大的文本检索功能。本程序是针对初学者设计的,旨在帮助开发者快速理解并...
`lucene入门小实例.txt` 文件中可能包含了一个简单的Lucene使用示例,例如: 1. 创建 `Directory` 对象,比如使用 `FSDirectory.open()` 打开一个文件系统的目录来存储索引。 2. 实例化 `Analyzer`,如使用 `...
通过这些学习资料,读者可以系统地学习搜索引擎的理论基础,掌握Lucene的核心功能,同时也能了解到如何在实际项目中应用这些技术,提升搜索系统的性能和用户体验。这些知识对于从事信息检索、网站开发、大数据分析等...
这个压缩包中的源码很可能是演示了如何构建和使用Lucene索引进行搜索的简单实例,对于初学者来说是一份很好的学习资料。通过阅读源码,你可以了解如何实际操作Lucene,从而加深对Lucene的理解。同时,实践是最好的...
随着对 Lucene 的深入学习,你可以利用这些功能来提升搜索体验。 总结,Lucene 4.8 作为一款强大的全文检索引擎,提供了丰富的工具和接口,使得开发者能够方便地构建自己的搜索引擎。通过理解其核心组件和工作流程...
Lucene通过引入外部分析器,如jieba分词或`je-analysis`,来解决中文分词问题。`je-analysis`是一个基于Java的中文分析器,它可以将中文文本分割成有意义的词语,为建立倒排索引提供基础。 ### Nutch入门 Nutch是...
**标题:“Lucene-入门”** Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发并维护。它是Java编写的一个开源项目,被广泛应用于构建搜索引擎或者在大型数据集上进行全文检索。Lucene提供了丰富的搜索...
Lucene 可以与其他开源项目结合,如 Solr 提供了 Web 接口和集群支持,Elasticsearch 建立在 Lucene 之上,提供了更高级的分布式搜索和分析功能。 总之,Lucene 是一个强大的搜索引擎框架,通过理解和掌握其核心...
- 提供的 `实例.docx` 文件可能包含具体操作步骤和常见问题解答,帮助你解决实际编程中遇到的问题。 6. **代码分析** - `Lucene 原理与代码分析完整版.pdf` 和 `Lucene in Action.pdf` 可能深入到 Lucene 的内部...
【Lucene】Lucene入门心得 Lucene是一个高性能、全文本搜索库,由Apache软件基金会开发,被广泛应用于各种搜索引擎的构建。...通过不断实践和学习,你将能更好地利用Lucene解决实际的全文搜索问题。
以上是Lucene入门的基本知识和关键概念,通过深入学习和实践,你可以掌握如何利用Lucene构建强大的全文搜索引擎。记住,实践中遇到的问题往往是最好的学习资源,不断尝试和解决,你将逐渐成为Lucene的专家。
Solr是建立在Lucene之上,为大型企业级应用提供搜索服务的平台。它不仅包含了Lucene的所有搜索功能,还添加了集群、分布式搜索、缓存、负载均衡、结果高亮、拼写检查、近似搜索等特性。Solr通过XML或JSON等格式的...
这个“Lucene入门demo”将帮助我们理解如何使用 Lucene 进行基本的索引和搜索操作。 **一、Lucene 的核心概念** 1. **索引(Indexing)**: 在 Lucene 中,索引是文档内容的预处理结果,类似于数据库中的索引。通过...
《最新全文检索 Lucene-5.2.1 入门经典实例》 Lucene是一个开源的全文检索库,由Apache软件基金会开发,广泛应用于各种信息检索系统。在5.2.1版本中,Lucene提供了更为高效和强大的搜索功能,为开发者提供了构建...
对于学习搜索引擎技术的人员来说,了解并掌握 Lucene 是非常重要的。 **1. Lucene 的基本概念** - **索引(Index)**:Lucene 将文档内容转化为可搜索的结构,这个过程称为索引。索引就像书籍的目录,可以快速定位...
【Lucene 入门教程】 Lucene 是一个由Apache软件基金会开发的开源全文检索引擎工具包,它并非一个完整的搜索引擎,而是提供了一个强大的架构,允许开发人员轻松地在他们的应用程序中集成全文检索功能。Lucene 支持...
### Lucene搜索引擎基础知识详解 #### 一、全文检索概述 **全文检索**是一种从文档集合中查找含有特定词语文档的技术。...Lucene作为一款成熟且广泛应用的全文检索工具包,无疑是学习全文检索技术的最佳起点之一。