lucene入门

lucene是一个高性能,可伸缩的全文搜索工具包,可以使用它为你的应用程序添加索引和搜索能力,下面是一个建立索引,并对索引进行查询的小例子


package com.lamp.lucene.util;

import java.io.File;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.NumberTools;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.junit.Test;

public class IndexDaoTest {

// 需要建立索引的数据源目录
public String dataPath = "D:\\javaEEProject\\Lucene\\dataPath";

// 具体的数据源文件路径
public String filePath = "D:\\javaEEProject\\Lucene\\dataPath\\JDBC.txt";
public String filePath2 = "D:\\javaEEProject\\Lucene\\dataPath\\反射机制.txt";

public IndexDao indexDao = new IndexDao();

/**
* 对数据源文件建立索引
*/
@Test
public void testSave() throws Exception {
File file = new File(dataPath);
traverseFile(file);
}

/**
* 对目录下的文件进行遍历并对后缀为.txt的文件建立索引
*/
public void traverseFile(File file) throws Exception {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File f : files) {
traverseFile(f);
}
}
if (file.getName().endsWith(".txt")) {
Document doc = FileToDocument.fileToDocument(file);
indexDao.save(doc);
}

}

/**
* 删除指定文件的索引文件
*/
@Test
public void testDelete() {
Term term = new Term("path", filePath);
indexDao.delete(term);
}

/**
* 更新指定文件的索引
*/
@Test
public void testUpdate() throws Exception {
Term term = new Term("path", filePath);
Document doc = FileToDocument.fileToDocument(filePath);
doc.getField("content").setValue("这是更新后的文件内容");
indexDao.update(term, doc);
}

/**
* 根据关键字对索引文件进行查询
*/
@Test
public void testSearch() {
String queryString = "操作";
// search(queryString, 0, 10)说的是从第一条匹配结果开始,返回最多前10条记录
QueryResult qr = indexDao.search(queryString, 0, 10);
System.out.println("总共有" + qr.getRecordCount() + "条匹配结果");
for (Document doc : qr.getRecordList()) {
System.out.println(doc.get("name"));
System.out.println(doc.get("content"));
System.out.println(NumberTools.stringToLong(doc.get("size")));
}
}

}





package com.lamp.lucene.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.NumberTools;

public class FileToDocument {

//对其name,content字段建立索引
public static Document fileToDocument(String dataPath) throws Exception {
File file = new File(dataPath);
Document doc = new Document();
doc.add(new Field("name", file.getName(), Store.YES, Index.ANALYZED));
doc.add(new Field("content", getContent(file), Store.YES,
Index.ANALYZED));
doc.add(new Field("size", NumberTools.longToString(file.length()), Store.YES,
Index.NOT_ANALYZED));
doc.add(new Field("path", file.getAbsolutePath(), Store.YES,
Index.NOT_ANALYZED));
return doc;

}

//返回文件内容
private static String getContent(File file) throws Exception {
StringBuffer buffer = new StringBuffer();
BufferedReader reader = null;
reader = new BufferedReader(new FileReader(file));
String str = "";
while (null != (str = reader.readLine())) {
buffer.append(str).append("\n");
}
return buffer.toString();
}

public static Document fileToDocument(File file) throws Exception {
Document doc = new Document();
doc.add(new Field("name", file.getName(), Store.YES, Index.ANALYZED));
doc.add(new Field("content", getContent(file), Store.YES,
Index.ANALYZED));
doc.add(new Field("size", NumberTools.longToString(file.length()), Store.YES,
Index.NOT_ANALYZED));
doc.add(new Field("path", file.getAbsolutePath(), Store.YES,
Index.NOT_ANALYZED));
return doc;
}

}





package com.lamp.lucene.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jeasy.analysis.MMAnalyzer;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.NumberTools;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeFilter;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;

public class IndexDao {

public String indexPath = "D:\\javaEEProject\\Lucene\\indexPath";

public Analyzer analyzer = new MMAnalyzer();// 词库分词

/**
* 添加/创建索引
*/
public void save(Document doc) {
IndexWriter indexWriter = null;
try {
indexWriter = new IndexWriter(indexPath, analyzer,
MaxFieldLength.LIMITED);
indexWriter.addDocument(doc);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
if (indexWriter != null) {
indexWriter.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

/**
* Term是搜索的最小单位,代表某个 Field 中的一个关键词,如:<title, lucene>
* new Term( "title", "lucene" );
* new Term( "id", "5" );
* new Term( "id", UUID );
*/
public void delete(Term term) {
IndexWriter indexWriter = null;
try {
indexWriter = new IndexWriter(indexPath, analyzer,
MaxFieldLength.LIMITED);
indexWriter.deleteDocuments(term);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
indexWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

/**
* 更新索引
*
* <pre>
* indexWriter.deleteDocuments(term);
* indexWriter.addDocument(doc);
* </pre>
*
* @param term
* @param doc
*/
public void update(Term term, Document doc) {
IndexWriter indexWriter = null;
try {
indexWriter = new IndexWriter(indexPath, analyzer,
MaxFieldLength.LIMITED);
indexWriter.updateDocument(term, doc);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
indexWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

/**
* <pre>
* totalPage = recordCount / pageSize;
* if (recordCount % pageSize > 0)
* totalPage++;
* </pre>
*
*/
/*
* public QueryResult search(String queryString, int firstResult, int
* maxResults) { try { // 1,把要搜索的文本解析为 Query String[] fields = { "name",
* "content" }; Map<String, Float> boosts = new HashMap<String, Float>();
* boosts.put("name", 3f); // boosts.put("content", 1.0f); 默认为1.0f
*
* QueryParser queryParser = new MultiFieldQueryParser(fields, analyzer,
* boosts); Query query = queryParser.parse(queryString);
*
* return search(query, firstResult, maxResults); } catch (Exception e) {
* throw new RuntimeException(e); } }
*/

public QueryResult search(String queryString, int firstResult,
int maxResults) {
try {
//在索引字段name,content上进行查询
String[] fields = { "name", "content" };
// 设置字段相关度,默认相关度为1f
Map<String, Float> boosts = new HashMap<String, Float>();
boosts.put("name", 5f);

QueryParser queryParser = new MultiFieldQueryParser(fields,
analyzer,boosts);
// 1,把要搜索的文本解析为 Query
Query query = queryParser.parse(queryString);

return search(query, firstResult, maxResults);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public QueryResult search(Query query, int firstResult, int maxResults) {
IndexSearcher indexSearcher = null;

try {
// 2,进行查询
indexSearcher = new IndexSearcher(indexPath);
//限定所查询文件的大小在200-1000之间
Filter filter = new RangeFilter("size",
NumberTools.longToString(200),
NumberTools.longToString(1000), true, true);

// 自定义排序,此处是按照文档大小进行排序
Sort sort = new Sort();
sort.setSort(new SortField("size")); // 默认为升序
// sort.setSort(new SortField("size", true));此为降序

//TopDocs topDocs = indexSearcher.search(query, filter, 10000, sort);

TopDocs topDocs = indexSearcher.search(query, null, 10000, sort);
//查询到的匹配结果数
int recordCount = topDocs.totalHits;
List<Document> recordList = new ArrayList<Document>();

// 准备高亮器,所谓高亮就是对查询到的关键字进行字体颜色的改变或者为其设置超链接
Formatter formatter = new SimpleHTMLFormatter("<font color='red'>",
"</font>");
Scorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(formatter, scorer);

Fragmenter fragmenter = new SimpleFragmenter(50);
highlighter.setTextFragmenter(fragmenter);

// 3,取出当前页的数据
int end = Math.min(firstResult + maxResults, topDocs.totalHits);
for (int i = firstResult; i < end; i++) {
ScoreDoc scoreDoc = topDocs.scoreDocs[i];
// 文档内部编号
int docSn = scoreDoc.doc;
// 根据编号取出相应的文档
Document doc = indexSearcher.doc(docSn);
// 返回高亮后的结果,如果当前属性值中没有出现关键字,会返回 null
String hc = highlighter.getBestFragment(analyzer, "content",
doc.get("content"));
if (hc == null) {
String content = doc.get("content");
int endIndex = Math.min(50, content.length());
// 最多前50个字符
hc = content.substring(0, endIndex);
}
doc.getField("content").setValue(hc);
recordList.add(doc);
}

// 返回结果
return new QueryResult(recordCount, recordList);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
indexSearcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}





package com.lamp.lucene.util;

import java.util.List;

import org.apache.lucene.document.Document;

/**
*
* QueryResult封装的是匹配结果数和Document集合
*/
public class QueryResult {
private int recordCount;
private List<Document> recordList;

public QueryResult(int recordCount, List<Document> recordList) {
super();
this.recordCount = recordCount;
this.recordList = recordList;
}

public int getRecordCount() {
return recordCount;
}

public void setRecordCount(int recordCount) {
this.recordCount = recordCount;
}

public List<Document> getRecordList() {
return recordList;
}

public void setRecordList(List<Document> recordList) {
this.recordList = recordList;
}

}



当然除了关键字查询外,还有文件大小范围进行查询,通配符查询,短语查询,布尔查询,示例如下


package com.lamp.lucene.util;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.NumberTools;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.WildcardQuery;
import org.junit.Test;


public class QueryTest {

public IndexDao indexDao = new IndexDao();

/**
* 关键字查询,即对指定的列上进行查询
*/
@Test
public void testTermQuery(){
Term term = new Term("name", "反射");
Query query = new TermQuery(term);
QueryResult result = indexDao.search(query, 0, 100);
printResult(result);
}

/**
* 按照文件大小范围进行查询,由于数字字符串比较大小时由于位数不同易产生问题,这里统一将数字用工具类
* NumberTools.longToString(long a)进行转化
*/
@Test
public void testRangeQuery(){
Term lowerTerm = new Term("size",NumberTools.longToString(200));
Term upperTerm = new Term("size",NumberTools.longToString(1000));

Query query = new RangeQuery(lowerTerm, upperTerm, true);
QueryResult result = indexDao.search(query, 0, 100);
printResult(result);
}

/**
* 通配符查询
* ‘?’代表一个字符,‘*’代表0个或多个字符
*/
@Test
public void testWildcardQuery(){
Term term = new Term("name","jd*");
Query query = new WildcardQuery(term);
QueryResult result = indexDao.search(query, 0, 100);
printResult(result);
}

/**
* 短语查询,比如你想查一首歌曲,里面有两个词语,但是这两个词语之间又隔着若干个词语,这时候可以选择短语查询
*/
@Test
public void testPhraseQuery(){
PhraseQuery query = new PhraseQuery();
query.add(new Term("content","反射"));
query.add(new Term("content","属性"));
//设定最大间隔数为10
query.setSlop(10);
QueryResult result = indexDao.search(query, 0, 100);
printResult(result);
}
/**
* 布尔查询,即对查询条件进行多项指定,不如大小,内容等
*/
@Test
public void testBoolQuery(){
Term lowerTerm = new Term("size",NumberTools.longToString(200));
Term upperTerm = new Term("size",NumberTools.longToString(1000));
Query query1 = new RangeQuery(lowerTerm, upperTerm, true);

PhraseQuery query2 = new PhraseQuery();
query2.add(new Term("content","反射"));
query2.add(new Term("content","属性"));
//设定最大间隔数为10
query2.setSlop(10);

BooleanQuery booleanQuery = new BooleanQuery();
//Occur.MUST指定的条件必须满足
booleanQuery.add(query1, Occur.MUST);
booleanQuery.add(query2, Occur.MUST);
QueryResult result = indexDao.search(booleanQuery, 0, 100);
printResult(result);
}

public void printResult(QueryResult result) {
System.out.println("找到的匹配结果有:" + result.getRecordCount() + "条");
for(Document doc : result.getRecordList()){
System.out.println(doc.get("name"));
System.out.println(doc.get("content"));
}
}

}



我使用的lucene版本是2.4,引入的jar包有lucene-core-2.4.0.jar,lucene-highlighter-2.4.0.jar,lucene-analyzers-2.4.0.jar,je-analysis-1.5.3.jar
MMAnalyzer 分词jar包(lucene-core-2.4.1.jar je-analysis-1.5.3.jar) Lucene中文分词器中的极易分词组件,包含jeasy.analysis.MMAnalyzer,以及依赖包lucene-core-2.4.1.jar! 立即下载

相关推荐

ubuntu20.04安装UE4+Airsim环境

版本UE4.27+Airsim1.81

玖茸的博客 3380

全文检索之lucene的优化篇--分词器

在创建索引库的基础上,加上中文分词器的,更好的支持中文的查询。引入jar包je-analysis-1.5.3.jar,极易分词.还是先看目录。          建立一个分词器的包,analyzer,准备一个AnalyzerTest的类.里面的代码如下,主要写了一个testAnalyzer的方法,测试多种分词器对于中文和英文的分词;为了可以看到效果,所以写了个analyze()的

mojolang 2775

OpenClaw Docker 安装问题解决全记录

控制面板无法加载(WebSocket 错误) | 确认 Nginx 配置中的 `Upgrade` 和 `Connection` 头正确 || 网关容器无法启动 | `docker compose logs openclaw-gateway`,检查权限、镜像名 |如需消除,使用 Let's Encrypt |- `<your-token>`:你的 OpenClaw 网关令牌(如 `b0e5ab...`)将 `<nas-ip>` 替换为你的群晖内网 IP(例如 `192.168.1.100`)。

u014490376的博客 2308

lucene MMAnalyzer 实现中文分词

先上代码: import java.io.IOException; import jeasy.analysis.MMAnalyzer; /** * 此次测试使用的是Lucene2.2 * @author 李晗 * */ public class Test { public static void main(String[] args) { ...

JAVA for GIS 421

Pythia: A Customizable Hardware Prefetching Framework Using Online Reinforcement Learning——“预取”论文解读

参考传送门: 1. Hardware Prefetching笔记 2. 全球百科——缓存预取 3. 百度百科——缓存数据预期技术 目录0. 什么是Hardware Prefetching(本节内容不包括在论文中)1. 简介1.1 关于Hardware Prefetching的一些关键信息1.2 现阶段方法的缺陷1.3 论文团队的目标1.4 核心思想2. 必要的背景知识介绍2.1 强化学习(Reinforcement learning)2.2 为什么说强化学习是一个好的解决思路3. 解决方法与思路3.1 Py

Pinkgranite86的博客 2166

Android车载桌面开发实战:从CarLauncher源码解析到自定义Launcher开发(Android 11)

本文深入解析了Android 11中CarLauncher的源码架构与核心模块,并提供了从零开始定制开发车载Launcher的完整实战指南。内容涵盖车载桌面的独特定位、驾驶场景优化、多屏协同、动态内容嵌入等核心挑战,以及如何构建符合安全规范、体验流畅的自定义车载桌面应用,是车载应用开发者提升系统级定制能力的实用参考。

weixin_29266647的博客 515

lucene可用中文分词IKAnalyzer,maven pom下载代码及配置文件

1.pom代码 <dependency> <groupId>com.janeluo</groupId> <artifactId>ikanalyzer</artifactId> <version>2012_u6</version> </dependency> 2.三个配置文件...

Buggggggg 1375

stm32H743IIT6 cubemx HAL USB UVC摄像头基础

stm32性能已经很强了, 可以驱动ov5640摄像头, 所以可以把摄像头接在stm32上, 当作一个摄像头驱动器, 连接到电脑上 开发环境: stm32cubemx 6.0.1 单片机: 自己做的stm32h743iit6核心板,兼容正点原子 学习资料: 圈圈学USB 鱼鹰谈单片机 从零开始学习USBhttps://to-run-away.blog.youkuaiyun.com/article/details/85038393 整个项目是基于CDC串口上修改 1 stm32 USB 代码概览 ..

紫枫洛天的博客 7750

MMAnalyzer极易中文分词组件

原文地址:http://xiarilian12.iteye.com/blog/855245 支持英文、数字、中文(简体)混合分词    常用的数量和人名的匹配    超过22万词的词库整理    实现正向最大匹配算法       //采用正向最大匹配的中文分词算法,相当于分词粒度等于0    MMAnalyzer analyzer = new MMAnalyzer();

ld_flex的专栏 2353

YOLO26优化:特征融合 | 一种新颖的多尺度特征融合iAFF,适配小目标检测

在YOLO26中如何使用:iAFF加入Neck替代Concat;

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 269

数字 IC 笔试面试必考点(1)FPGA 芯片架构

FPGA 芯片架构是非常重要的,如果你不了解 FPGA 芯片内部的详细架构,那么...

新芯设计的博客 2807

Lucene入门

全文检索是将整本书、整篇文章中的任意内容信息查找出来的检索。它可以根据需要获得全文中有关章、节、段、句、词等信息,计算机程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时根据建立的索引查找,类似于通过字典的检索字表查字的过程。

weixin_44270855的博客 806

【实战】基于 Inner-IoU 的 YOLOv8 优化指南:显著提升检测精度

Inner-IoU 凭借辅助边框的创新设计,成功解决了传统 IoU 损失在小目标、遮挡场景下的收敛难题,为 YOLOv8 注入了更强的定位能力。从原理剖析到代码集成,本教程已为你铺就了一条“精度提升”的实战路径。现在,不妨亲自上手尝试,让你的目标检测模型在各类数据集上都能交出一份“精度优异”的答卷——相信我,当你看到检测框精准贴合目标的那一刻,你会明白这份尝试的价值。

m0_64661770的博客 107

Lucene从入门到使用

第一节:lucene入门阶段 1.什么是Lucene?         Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。——《百度百科》 2.全文...

Null的博客 1万+

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Lucene的入门案例

   最近在网上找视频学习了Lucene的相关知识,根据视频内容以及其他资料简单总结下Lucene的相关知识点。    Lucene是apache软件基金会的一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在...

Java学习 323

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

lucene入门02

582

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

lucene入门1

lucene入门 1.创建索引 2.查询索引

zzzjavazzz的博客 182

lucene全文检索入门

欢迎使用lucene 非结构化数据顺序扫描很慢,对结构化数据的搜索却相对较快(由于结构化数据有一定的结构可以采取一定的搜索算法加快速度),那么把我们的非结构化数据想办法弄得有一定结构不就行了吗?关系数据库中存储的都是结构化数据,因此很检索都比较快。 从非结构化数据中提取出数据的然后重新组织成结构化数据的信息,我们称之索引。即为文本数据建立类似字典目录,从而提高检索速度。 全文检索的特点: (1...

weixin_44675503的博客 697

java lucene 例子_Lucene第一个入门学习例子

看Lucene in Action的时候,练习的一个入门例子。在使用Lucene进行文本内容搜索前,需要先对指定的目录下的文件进行建立索引,代码如下:importjava.io.File;importjava.io.FileFilter;importjava.io.FileReader;importjava.io.IOException;importorg.apache.lucene.a...

weixin_33871933的博客 249

lucene4.4入门实践

最近需要用到lucene,使用最新版本4.6的版本,发现比较以前学习的3.0版本有很多的改变,包括各种参数配置,而网上搜索到的大部分都是3.0版本的教程,于是只好自己动手,好在有基础,不难...      首先创建索引,其实我很久不用lucene了,以前学习的差不多都忘记了,不过我还记得创建索引对象IndexWriter,使用这个对象,根据eclipse的代码提示,差不多就可以完成了

乄浅醉的专栏 966
上一篇: java之插入排序
下一篇: lucene之分词器
lk231_java
博客等级 码龄15年 0粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值