Lucene全文搜索学习笔记(一)
来源:互联网 发布:写日志的软件知乎 编辑:程序博客网 时间:2024/04/29 21:28
个人笔记之用,如有错误,恳请批评指正。
什么是lucene?
Lucene是apache软件基金会发布的一个开放源代码的全文检索引擎工具包,由资深全文检索专家Doug Cutting所撰写,它是一个全文检索引擎的架构,提供了完整的创建索引和查询索引,以及部分文本分析的引擎,Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎,Lucene在全文检索领域是一个经典的祖先,现在很多检索引擎都是在其基础上创建的,思想是相通的。
即:Lucene是根据关健字来搜索的文本搜索工具,只能在某个网站内部搜索文本内容,不能跨网站搜索。
Lucene通常用在什么地方?
Lucece不能用在互联网搜索(即像百度那样),只能用在网站内部的文本搜索(即只能在CRM,RAX,ERP内部使用),但思想是相通的。
为什么网站内部有些地方要用Lucene来索搜,而不全用SQL来搜索?
(1)SQL只能针对数据库表搜索,不能直接针对硬盘上的文本搜索
(2)SQL没有相关度排名
(3)SQL搜索结果没有关健字高亮显示
(4)SQL需要数据库的支持,数据库本身需要内存开销较大,例如:Oracle
(5)SQL搜索有时较慢,尤其是数据库不在本地时,超慢,例如:Oracle
使用Lucene的流程图?
创建索引库:
1) 创建JavaBean对象
2) 创建Docment对象
3) 将JavaBean对象所有的属性值,均放到Document对象中去,属性名可以和JavaBean相同或不同
4) 创建IndexWriter对象
5) 将Document对象通过IndexWriter对象写入索引库中
6) 关闭IndexWriter对象
根据关键字查询索引库中的内容:
1) 创建IndexSearcher对象
2) 创建QueryParser对象
3) 创建Query对象来封装关键字
4) 用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准
5) 获取符合条件的编号
6) 用indexSearcher对象去索引库中查询编号对应的Document对象
7) 将Document对象中的所有属性取出,再封装回JavaBean对象中去,并加入到集合中保存,以备将之用。
Lucene快速入门
导入Lucene相关的jar包
lucene-core-3.0.2.jar【Lucene核心】
lucene-analyzers-3.0.2.jar【分词器】
lucene-highlighter-3.0.2.jar【Lucene会将搜索出来的字,高亮显示,提示用户】
lucene-memory-3.0.2.jar【索引库优化策略】
编写代码:虚拟Article bean对象
package cn.ustb.lucene.entity;public class Article {private Integer id;private String title;private String content;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public Article() {super();}public Article(Integer id, String title, String content) {super();this.id = id;this.title = title;this.content = content;}}LuceneApp:
package cn.ustb.lucene.entity;import java.io.File;import java.util.ArrayList;import java.util.List;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.Field.Index;import org.apache.lucene.document.Field.Store;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriter.MaxFieldLength;import org.apache.lucene.queryParser.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.util.Version;import org.junit.Test;public class FirstLucene {public void createIndexDB(Article article){//documentDocument document = new Document();//创建lucene文档对象,并添加字段/*FIELD:: * Store.YES表示把当前字段存到文档中,Store.NO表示 不把当前字段存到文档中 * Index: * ANALYZED,表示当前字段建立索引,并且进行分词,产生多个term * NOT_ANALYZED,表示当前字段建立索引,但不进行分词,整个字段值作为一个整体,产生一个term * NO,不创建索引,以后不能用此字段查询 */document.add(new Field("id", article.getId().toString(), Store.YES, Index.NOT_ANALYZED));document.add(new Field("title",article.getTitle(),Store.YES,Index.ANALYZED));document.add(new Field("content",article.getContent(),Store.YES,Index.ANALYZED));Directory directory = null;Analyzer analyzer = null;IndexWriter indexWriter = null;try {//指定索引库目录directory = FSDirectory.open(new File("F:/java/practice/luceneDir"));//指定分词器 版本一般用最高版本analyzer = new StandardAnalyzer(Version.LUCENE_30);//创建索引库管理对象/**创建索引库管理对象(主要用来增删改索引库信息)* MaxFieldLength,用于限制Field的大小。这个变量可以让用户有计划地*对大文档Field进行截取。假如取值为10000,就只索引每个Field的前*10000个Term(关键字)。其它的部分都不会被Lucene索引,也不能被搜索到。*/indexWriter = new IndexWriter(directory, analyzer, MaxFieldLength.LIMITED);//添加文档对象到索引库管理对象indexWriter.addDocument(document);//提交到索引库indexWriter.commit();} catch (Exception e) {e.printStackTrace();}//关闭finally{if(indexWriter!=null){try {indexWriter.close();} catch (Exception e) {e.printStackTrace();}}}}public void findIndexDB(String keyWords){List<Article> articleList = new ArrayList<Article>();try {FSDirectory directory = FSDirectory.open(new File("F:/java/practice/luceneDir"));//分词器 :和存入时要一致Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);//索引库搜索者IndexSearcher indexSearcher = new IndexSearcher(directory);//指定查询解析器//参数一:版本号,一般选择最高,参数二:字段名,参数三:分词器QueryParser queryParser = new QueryParser(Version.LUCENE_30, "title", analyzer);//把查询关键字交给查询解析器,如果由多个单词组成,将匹配多个term 关键字,只要能匹配上任意一个单词都可以返回Query query = queryParser.parse(keyWords);//查询解析库//参数1:指定的查询解析器,参数二:指定返回记录条数TopDocs topDocs = indexSearcher.search(query, 5);System.out.println("实际索引库中匹配到的总条数为:"+topDocs.totalHits);System.out.println("返回的记录(ID)条数为:"+topDocs.scoreDocs.length);ScoreDoc[] scoreDocs = topDocs.scoreDocs;for (ScoreDoc scoreDoc : scoreDocs) {System.out.println("当前的文档积分是:"+scoreDoc.score);System.out.println("当前的文档编号是:"+scoreDoc.doc);//根据文档查看真正的文档对象Document document = indexSearcher.doc(scoreDoc.doc);System.out.println("真正文档的内容是:id:"+document.get("id")+";title:"+document.get("title")+";content:"+document.get("content"));}} catch (Exception e) {e.printStackTrace();}}@Testpublic void testIn(){Article article = new Article(1, "挖掘机修理哪家强?", "山东济南找蓝翔");createIndexDB(article);}@Testpublic void testOut(){String keyword = "挖掘机";findIndexDB(keyword);}}
新增操作说明
关键步骤与代码解说:
1.构建索引库
Directory directory = FSDirectory.open(new File("索引库目录"));
2.指定分词器,版本一般指定为最高
Analyzer analyzer = newStandardAnalyzer(Version.LUCENE_30);
3.创建文档对象,并添加相关字段值
Document doc = new Document();
doc.add(new Field("Id",goods.getGoodsId().toString(),Store.YES,Index.NOT_ANALYZED));
4.创建增删改索引库的操作对象,添加文档并提交
IndexWriter indexWriter =new IndexWriter(directory,analyzer, MaxFieldLength.LIMITED);
indexWriter.addDocument(doc);
indexWriter.commit();
5.关闭操作对象
查询操作说明
关键步骤与代码解说:
1.打开索引库
directory= FSDirectory.open(new File("索引库目录"));
2。创建查询分词器,版本号与写入文档的查询分词器一样
Analyzer analyzer = newStandardAnalyzer(Version.LUCENE_30);
3。创建查询解析器,参数为版本号,查询字段名,分词器
QueryParser parser = new QueryParser(Version.LUCENE_30,"content",analyzer);
4。构建查询信息对象
Query query = parser.parse(keyWord);
5。构建查询工具
searcher = new IndexSearcher(directory);
6。通过查询工具执行查询。参数1,查询信息对象;参数2。返回记录数;TopDocs包括总记录数、文档重要信息(编号)的列表等
TopDocs topDocx=searcher.search(query,20);
7。根据文档编号遍历真正的文档
ScoreDoc sd[] = topDocx.scoreDocs;
for(ScoreDoc scoreDoc:sd){
。。。
Document doc =searcher.doc(scoreDoc.doc);
8。转为java对象 setter(doc.get("param"));
9.关闭查询操作对象
下一步:
封装及优化,待续...
- Lucene全文搜索学习笔记(一)
- Lucene全文搜索学习笔记(二)
- Lucene全文搜索学习笔记(三)
- Lucene全文检索学习笔记(一):lucene的应用
- Lucene全文搜索学习
- 全文检索lucene学习笔记(一)
- 全文检索lucene学习笔记(一)
- Lucene连接数据库进行全文搜索初探(一)
- lucene compass 学习系列 笔记 一,纯lucene 构建搜索
- 【搜索那些事】细谈lucene(一)初识全文资源检索框架lucene
- 【搜索那些事】细谈lucene(一)初识全文资源检索框架lucene
- 【搜索那些事】细谈lucene(一)初识全文资源检索框架lucene
- 搜索-Lucene学习笔记
- Lucene学习笔记(一)-------Lucene基础
- Lucene学习总结(一):全文检索的工作流程
- Lucene学习(一):全文检索的基本原理
- Lucene学习笔记(一)
- lucene学习笔记(一)
- 基于python标准库对XML文件的保存和加载
- 一个Linux下C线程池的实现(转)
- jzoj 1219 Num
- JavaScript将继承部分封装成函数extend
- 获取xmlString字符串中节点属性值
- Lucene全文搜索学习笔记(一)
- workbench出现there is not editable because there is no primary key
- 38
- 问题三十五: 怎么用ray tracing画二次曲面(quadratic surfaces)(2)——单页双曲面、双页双曲面、椭圆锥面、椭圆柱面
- 通过nfs加载根文件系统
- URL字符串中空格转化
- 干货分享——shutdown命令
- maven 汇总
- thinkphp连接数据库具体步骤