`
yangwei0915
  • 浏览: 469114 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Lucene学习之Lucene入门暨中文文件搜索问题的解决

 
阅读更多

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包,才能正常编译运行。

在编写这个例子的时候,参考了网上其他朋友的文章及代码,在此一并感谢!

分享到:
评论

相关推荐

    毕业论文-安全跳转页面-整站商业源码.zip

    毕业论文-安全跳转页面-整站商业源码.zip

    实训商业源码-视频解析-毕业设计.zip

    实训商业源码-视频解析-毕业设计.zip

    实训商业源码-小小素材库V7.8.45 小程序前端+后端-毕业设计.zip

    实训商业源码-小小素材库V7.8.45 小程序前端+后端-毕业设计.zip

    毕业论文-二刺螈导航-整站商业源码.zip

    毕业论文-二刺螈导航-整站商业源码.zip

    AI在MES中的应用.pdf

    AI在MES中的应用.pdf

    基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例

    基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例,该项目是个人毕设项目,答辩评审分达到98分,代码都经过调试测试,确保可以运行!欢迎下载使用,可用于小白学习、进阶。该资源主要针对计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者下载使用,亦可作为期末课程设计、课程大作业、毕业设计等。项目整体具有较高的学习借鉴价值!基础能力强的可以在此基础上修改调整,以实现不同的功能。 基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了Cesium的一些基础示例基于Vue 3实现的Cesium大屏可视化项目源代码,展示了

    【跨境电商营销】亚马逊蓝牙音箱产品数据分析:市场表现与关键词影响研究

    内容概要:该报告由Co.media可美亚发布,基于Amazon平台上的蓝牙音箱产品数据,通过网页工具抓取并清理了772笔交易信息,最终分析了248笔有效数据。报告揭示了评论数高的产品通常售价较高,但低价并非获得高评级的有效手段。高频关键词如“Speaker”、“Bluetooth”、“Smart”、“Wireless”等能显著提升搜索匹配度和销售排名,尤其是前20名产品大多带有这些关键词。此外,价格较低的产品多归类为手机&配件,而价格较高的则归类为电子产品。前50名产品在金额、评论和星数方面具有明显优势,而新产品若想快速进入搜索排名前10,则需重点投入于产品定价和评论星数的提升。 适合人群:希望拓展北美市场的中国品牌企业、从事跨境电商的从业者以及对蓝牙音箱市场感兴趣的投资者。 使用场景及目标:①帮助企业了解蓝牙音箱在北美市场的竞争态势;②指导企业优化产品标题中的关键词选择,以提高搜索排名;③为制定产品定价策略和提升用户评价提供数据支持。 其他说明:Co.media可美亚是一家专注于为中国品牌提供跨境整合营销服务的公司,尤其擅长帮助企业在北美市场建立品牌知名度和竞争力。报告中涉及的数据分析方法包括统计回归分析,用于评估不同因素对搜索排名和销售排名的影响。

    基于Go+python实现的网络异常流量检测系统+源码+GUI界面(毕业设计&课程设计&项目开发)

    基于Go+python实现的网络异常流量检测系统+源码+GUI界面,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用 基于Go+python实现的网络异常流量检测系统+源码+GUI界面,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ 基于Go+python实现的网络异常流量检测系统+源码+GUI界面,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用 基于Go+python实现的网络异常流量检测系统+源码+GUI界面,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用 基于Go+python实现的网络异常流量检测系统+源码+GUI界面,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用 基于Go+python实现的网络异常流量检测系统+源码+GUI界面,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用

    ANSYS SpaceClaim直接建模技术.pdf

    ANSYS SpaceClaim直接建模技术.pdf

    毕业论文-超人配送代驾跑腿小程序V1.5.10 前端+后端-整站商业源码.zip

    毕业论文-超人配送代驾跑腿小程序V1.5.10 前端+后端-整站商业源码.zip

    毕业论文-wx码支付-整站商业源码.zip

    毕业论文-wx码支付-整站商业源码.zip

    实训商业源码-智能AI雷达名片+1.6.7-毕业设计.zip

    实训商业源码-智能AI雷达名片+1.6.7-毕业设计.zip

    ANSYS网格划分.pdf

    ANSYS网格划分.pdf

    3D变形技术在汽车造型设计中的应用.pdf

    3D变形技术在汽车造型设计中的应用.pdf

    ANSYS高级流体动力学培训手册2.pdf

    ANSYS高级流体动力学培训手册2.pdf

    vosk-model-small-cn-022

    vosk-model-small-cn-022

    实训商业源码-视频小店V1.0.7 原版-毕业设计.zip

    实训商业源码-视频小店V1.0.7 原版-毕业设计.zip

    HR_S30-1800.hard

    HR_S30-1800.hard

    C++语言任意进制转换(1).zip

    C++语言任意进制转换(1).zip

    AGV无人配送系统在美的开利厂房应用介绍.pdf

    AGV无人配送系统在美的开利厂房应用介绍.pdf

Global site tag (gtag.js) - Google Analytics