lucene初体验
来源:互联网 发布:seo原创软文代写兼职 编辑:程序博客网 时间:2024/05/23 23:06
通过学习之后做一下总结吧:
什么是lucene
Lucene是apache旗下的顶级项目,是一个全文检索工具包
Lucene就是一个可以创建全文检索引擎系统的一堆jar包.可以使用它来构建全文检索引擎系统,但是它不能独立运行。
Lucene应用领域
1.互联网全文检索引擎(比如百度, 谷歌, 必应)
2.站内全文检索引擎(淘宝, 京东搜索功能)
3.优化数据库查询(因为数据库中使用like关键字是全表扫描也就是顺序扫描算法,查询慢)
Lucene下载官方网站:http://lucene.apache.org/
Lucene结构
索引:
域名:词 这样的形式,
它里面有指针执行这个词来源的文档
索引库:
放索引的文件夹(这个文件夹可以自己随意创建,在里面放索引就是索引库)
Term词元: 就是一个词, 是lucene中词的最小单位
文档:
Document对象,一个Document中可以有多个Field域对象,Field域对象中是key value键值对的形式:有域名和域值,一个document就是数据库表中的一条记录, 一个Filed域对象就是数据库表中的一行一列。这是一个通用的存储结构.
创建索引和所有时所用的分词器必须一致
域的详细介绍
是否分词:
分词的作用是为了索引
需要分词: 文件名称, 文件内容
不需要分词: 不需要索引的域不需要分词,还有就是分词后无意义的域不需要分词
比如: id, 身份证号
是否索引:
索引的的目的是为了搜索.
需要搜索的域就一定要创建索引,只有创建了索引才能被搜索出来
不需要搜索的域可以不创建索引
需要索引: 文件名称, 文件内容, id, 身份证号等
不需要索引: 比如图片地址不需要创建索引,e:\\xxx.jpg,因为根据图片地址搜索无意义
是否存储:
存储的目的是为了显示.
是否存储看个人需要,存储就是将内容放入Document文档对象中保存出来,会额外占用磁盘空间, 如果搜索的时候需要马上显示出来可以放入document中也就是要存储,这样查询显示速度快, 如果不是马上立刻需要显示出来,则不需要存储,因为额外占用磁盘空间不划算.
域的各种类型
Field类
数据类型
Analyzed
是否分析
Indexed
是否索引
Stored
是否存储
说明
StringField(FieldName, FieldValue,Store.YES))
字符串
N
Y
Y或N
这个Field用来构建一个字符串Field,但是不会进行分析,会将整个串存储在索引中,比如(订单号,姓名等)
是否存储在文档中用Store.YES或Store.NO决定
LongField(FieldName, FieldValue,Store.YES)
Long型
Y
Y
Y或N
这个Field用来构建一个Long数字型Field,进行分析和索引,比如(价格)
是否存储在文档中用Store.YES或Store.NO决定
StoredField(FieldName, FieldValue)
重载方法,支持多种类型
N
N
Y
这个Field用来构建不同类型Field
不分析,不索引,但要Field存储在文档中
TextField(FieldName, FieldValue, Store.NO)
或
TextField(FieldName, reader)
字符串
或
流
Y
Y
Y或N
如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略.
需要源码的点击这个链接下载:项目源码下载
package cn.itheima.lucene;import java.io.File;import java.util.ArrayList;import java.util.List;import org.apache.commons.io.FileUtils;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.TextField;import org.apache.lucene.document.Field.Store;import org.apache.lucene.document.LongField;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.index.Term;import org.apache.lucene.store.Directory;import org.apache.lucene.store.FSDirectory;import org.apache.lucene.util.Version;import org.junit.Test;import org.wltea.analyzer.lucene.IKAnalyzer;public class IndexManagerTest {@Testpublic void testIndexCreate() throws Exception{//创建文档列表,保存多个DocuemntList<Document> docList = new ArrayList<Document>();//指定文件所在目录File dir = new File("E:\\01传智课程\\黑28期0523\\Lucene&Solr\\01.参考资料\\searchsource"); //循环文件夹取出文件for(File file : dir.listFiles()){//文件名称String fileName = file.getName();//文件内容String fileContext = FileUtils.readFileToString(file);//文件大小Long fileSize = FileUtils.sizeOf(file);//文档对象,文件系统中的一个文件就是一个Docuemnt对象Document doc = new Document();//第一个参数:域名//第二个参数:域值//第三个参数:是否存储,是为yes,不存储为no/*TextField nameFiled = new TextField("fileName", fileName, Store.YES);TextField contextFiled = new TextField("fileContext", fileContext, Store.YES);TextField sizeFiled = new TextField("fileSize", fileSize.toString(), Store.YES);*///是否分词:要,因为它要索引,并且它不是一个整体,分词有意义//是否索引:要,因为要通过它来进行搜索//是否存储:要,因为要直接在页面上显示TextField nameFiled = new TextField("fileName", fileName, Store.YES);//是否分词: 要,因为要根据内容进行搜索,并且它分词有意义//是否索引: 要,因为要根据它进行搜索//是否存储: 可以要也可以不要,不存储搜索完内容就提取不出来TextField contextFiled = new TextField("fileContext", fileContext, Store.NO);//是否分词: 要, 因为数字要对比,搜索文档的时候可以搜大小, lunene内部对数字进行了分词算法//是否索引: 要, 因为要根据大小进行搜索//是否存储: 要, 因为要显示文档大小LongField sizeFiled = new LongField("fileSize", fileSize, Store.YES);//将所有的域都存入文档中doc.add(nameFiled);doc.add(contextFiled);doc.add(sizeFiled);//将文档存入文档集合中docList.add(doc);}//创建分词器,StandardAnalyzer标准分词器,标准分词器对英文分词效果很好,对中文是单字分词Analyzer analyzer = new IKAnalyzer();//指定索引和文档存储的目录Directory directory = FSDirectory.open(new File("E:\\dic"));//创建写对象的初始化对象IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);//创建索引和文档写对象IndexWriter indexWriter = new IndexWriter(directory, config);//将文档加入到索引和文档的写对象中for(Document doc : docList){indexWriter.addDocument(doc);}//提交indexWriter.commit();//关闭流indexWriter.close();}@Testpublic void testIndexDel() throws Exception{//创建分词器,StandardAnalyzer标准分词器,标准分词器对英文分词效果很好,对中文是单字分词Analyzer analyzer = new IKAnalyzer();//指定索引和文档存储的目录Directory directory = FSDirectory.open(new File("E:\\dic"));//创建写对象的初始化对象IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);//创建索引和文档写对象IndexWriter indexWriter = new IndexWriter(directory, config);//删除所有//indexWriter.deleteAll();//根据名称进行删除//Term词元,就是一个词, 第一个参数:域名, 第二个参数:要删除含有此关键词的数据indexWriter.deleteDocuments(new Term("fileName", "apache"));//提交indexWriter.commit();//关闭indexWriter.close();}/** * 更新就是按照传入的Term进行搜索,如果找到结果那么删除,将更新的内容重新生成一个Document对象 * 如果没有搜索到结果,那么将更新的内容直接添加一个新的Document对象 * @throws Exception */@Testpublic void testIndexUpdate() throws Exception{//创建分词器,StandardAnalyzer标准分词器,标准分词器对英文分词效果很好,对中文是单字分词Analyzer analyzer = new IKAnalyzer();//指定索引和文档存储的目录Directory directory = FSDirectory.open(new File("E:\\dic"));//创建写对象的初始化对象IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);//创建索引和文档写对象IndexWriter indexWriter = new IndexWriter(directory, config);//根据文件名称进行更新Term term = new Term("fileName", "web");//更新的对象Document doc = new Document();doc.add(new TextField("fileName", "xxxxxx", Store.YES));doc.add(new TextField("fileContext", "think in java xxxxxxx", Store.NO));doc.add(new LongField("fileSize", 100L, Store.YES));//更新indexWriter.updateDocument(term, doc);//提交indexWriter.commit();//关闭indexWriter.close();}}
//////////////////////////////////////////////////////////////////////////////////////
package cn.itheima.lucene;import java.io.File;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.Term;import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;import org.apache.lucene.queryparser.classic.QueryParser;import org.apache.lucene.search.BooleanClause.Occur;import org.apache.lucene.search.BooleanQuery;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.MatchAllDocsQuery;import org.apache.lucene.search.NumericRangeQuery;import org.apache.lucene.search.Query;import org.apache.lucene.search.ScoreDoc;import org.apache.lucene.search.TermQuery;import org.apache.lucene.search.TopDocs;import org.apache.lucene.store.Directory;import org.apache.lucene.store.FSDirectory;import org.junit.Test;import org.wltea.analyzer.lucene.IKAnalyzer;public class IndexSearchTest {@Testpublic void testIndexSearch() throws Exception{//创建分词器(创建索引和所有时所用的分词器必须一致)Analyzer analyzer = new IKAnalyzer();//创建查询对象,第一个参数:默认搜索域, 第二个参数:分词器//默认搜索域作用:如果搜索语法中指定域名从指定域中搜索,如果搜索时只写了查询关键字,则从默认搜索域中进行搜索QueryParser queryParser = new QueryParser("fileContext", analyzer);//查询语法=域名:搜索的关键字Query query = queryParser.parse("fileName:web");//指定索引和文档的目录Directory dir = FSDirectory.open(new File("E:\\dic"));//索引和文档的读取对象IndexReader indexReader = IndexReader.open(dir);//创建索引的搜索对象IndexSearcher indexSearcher = new IndexSearcher(indexReader);//搜索:第一个参数为查询语句对象, 第二个参数:指定显示多少条TopDocs topdocs = indexSearcher.search(query, 5);//一共搜索到多少条记录System.out.println("=====count=====" + topdocs.totalHits);//从搜索结果对象中获取结果集ScoreDoc[] scoreDocs = topdocs.scoreDocs;for(ScoreDoc scoreDoc : scoreDocs){//获取docIDint docID = scoreDoc.doc;//通过文档ID从硬盘中读取出对应的文档Document document = indexReader.document(docID);//get域名可以取出值 打印System.out.println("fileName:" + document.get("fileName"));System.out.println("fileSize:" + document.get("fileSize"));System.out.println("============================================================");}}@Testpublic void testIndexTermQuery() throws Exception{//创建分词器(创建索引和所有时所用的分词器必须一致)Analyzer analyzer = new IKAnalyzer();//创建词元:就是词, Term term = new Term("fileName", "apache");//使用TermQuery查询,根据term对象进行查询TermQuery termQuery = new TermQuery(term);//指定索引和文档的目录Directory dir = FSDirectory.open(new File("E:\\dic"));//索引和文档的读取对象IndexReader indexReader = IndexReader.open(dir);//创建索引的搜索对象IndexSearcher indexSearcher = new IndexSearcher(indexReader);//搜索:第一个参数为查询语句对象, 第二个参数:指定显示多少条TopDocs topdocs = indexSearcher.search(termQuery, 5);//一共搜索到多少条记录System.out.println("=====count=====" + topdocs.totalHits);//从搜索结果对象中获取结果集ScoreDoc[] scoreDocs = topdocs.scoreDocs;for(ScoreDoc scoreDoc : scoreDocs){//获取docIDint docID = scoreDoc.doc;//通过文档ID从硬盘中读取出对应的文档Document document = indexReader.document(docID);//get域名可以取出值 打印System.out.println("fileName:" + document.get("fileName"));System.out.println("fileSize:" + document.get("fileSize"));System.out.println("============================================================");}}@Testpublic void testNumericRangeQuery() throws Exception{//创建分词器(创建索引和所有时所用的分词器必须一致)Analyzer analyzer = new IKAnalyzer();//根据数字范围查询//查询文件大小,大于100 小于1000的文章//第一个参数:域名 第二个参数:最小值, 第三个参数:最大值, 第四个参数:是否包含最小值, 第五个参数:是否包含最大值Query query = NumericRangeQuery.newLongRange("fileSize", 100L, 1000L, true, true);//指定索引和文档的目录Directory dir = FSDirectory.open(new File("E:\\dic"));//索引和文档的读取对象IndexReader indexReader = IndexReader.open(dir);//创建索引的搜索对象IndexSearcher indexSearcher = new IndexSearcher(indexReader);//搜索:第一个参数为查询语句对象, 第二个参数:指定显示多少条TopDocs topdocs = indexSearcher.search(query, 5);//一共搜索到多少条记录System.out.println("=====count=====" + topdocs.totalHits);//从搜索结果对象中获取结果集ScoreDoc[] scoreDocs = topdocs.scoreDocs;for(ScoreDoc scoreDoc : scoreDocs){//获取docIDint docID = scoreDoc.doc;//通过文档ID从硬盘中读取出对应的文档Document document = indexReader.document(docID);//get域名可以取出值 打印System.out.println("fileName:" + document.get("fileName"));System.out.println("fileSize:" + document.get("fileSize"));System.out.println("============================================================");}}@Testpublic void testBooleanQuery() throws Exception{//创建分词器(创建索引和所有时所用的分词器必须一致)Analyzer analyzer = new IKAnalyzer();//布尔查询,就是可以根据多个条件组合进行查询//文件名称包含apache的,并且文件大小大于等于100 小于等于1000字节的文章BooleanQuery query = new BooleanQuery();//根据数字范围查询//查询文件大小,大于100 小于1000的文章//第一个参数:域名 第二个参数:最小值, 第三个参数:最大值, 第四个参数:是否包含最小值, 第五个参数:是否包含最大值Query numericQuery = NumericRangeQuery.newLongRange("fileSize", 100L, 1000L, true, true);//创建词元:就是词, Term term = new Term("fileName", "apache");//使用TermQuery查询,根据term对象进行查询TermQuery termQuery = new TermQuery(term);//Occur是逻辑条件//must相当于and关键字,是并且的意思//should,相当于or关键字或者的意思//must_not相当于not关键字, 非的意思//注意:单独使用must_not 或者 独自使用must_not没有任何意义query.add(termQuery, Occur.MUST);query.add(numericQuery, Occur.MUST);//指定索引和文档的目录Directory dir = FSDirectory.open(new File("E:\\dic"));//索引和文档的读取对象IndexReader indexReader = IndexReader.open(dir);//创建索引的搜索对象IndexSearcher indexSearcher = new IndexSearcher(indexReader);//搜索:第一个参数为查询语句对象, 第二个参数:指定显示多少条TopDocs topdocs = indexSearcher.search(query, 5);//一共搜索到多少条记录System.out.println("=====count=====" + topdocs.totalHits);//从搜索结果对象中获取结果集ScoreDoc[] scoreDocs = topdocs.scoreDocs;for(ScoreDoc scoreDoc : scoreDocs){//获取docIDint docID = scoreDoc.doc;//通过文档ID从硬盘中读取出对应的文档Document document = indexReader.document(docID);//get域名可以取出值 打印System.out.println("fileName:" + document.get("fileName"));System.out.println("fileSize:" + document.get("fileSize"));System.out.println("============================================================");}}@Testpublic void testMathAllQuery() throws Exception{//创建分词器(创建索引和所有时所用的分词器必须一致)Analyzer analyzer = new IKAnalyzer();//查询所有文档MatchAllDocsQuery query = new MatchAllDocsQuery();//指定索引和文档的目录Directory dir = FSDirectory.open(new File("E:\\dic"));//索引和文档的读取对象IndexReader indexReader = IndexReader.open(dir);//创建索引的搜索对象IndexSearcher indexSearcher = new IndexSearcher(indexReader);//搜索:第一个参数为查询语句对象, 第二个参数:指定显示多少条TopDocs topdocs = indexSearcher.search(query, 5);//一共搜索到多少条记录System.out.println("=====count=====" + topdocs.totalHits);//从搜索结果对象中获取结果集ScoreDoc[] scoreDocs = topdocs.scoreDocs;for(ScoreDoc scoreDoc : scoreDocs){//获取docIDint docID = scoreDoc.doc;//通过文档ID从硬盘中读取出对应的文档Document document = indexReader.document(docID);//get域名可以取出值 打印System.out.println("fileName:" + document.get("fileName"));System.out.println("fileSize:" + document.get("fileSize"));System.out.println("============================================================");}}@Testpublic void testMultiFieldQueryParser() throws Exception{//创建分词器(创建索引和所有时所用的分词器必须一致)Analyzer analyzer = new IKAnalyzer();String [] fields = {"fileName","fileContext"};//从文件名称和文件内容中查询,只有含有apache的就查出来MultiFieldQueryParser multiQuery = new MultiFieldQueryParser(fields, analyzer);//输入需要搜索的关键字Query query = multiQuery.parse("apache");//指定索引和文档的目录Directory dir = FSDirectory.open(new File("E:\\dic"));//索引和文档的读取对象IndexReader indexReader = IndexReader.open(dir);//创建索引的搜索对象IndexSearcher indexSearcher = new IndexSearcher(indexReader);//搜索:第一个参数为查询语句对象, 第二个参数:指定显示多少条TopDocs topdocs = indexSearcher.search(query, 5);//一共搜索到多少条记录System.out.println("=====count=====" + topdocs.totalHits);//从搜索结果对象中获取结果集ScoreDoc[] scoreDocs = topdocs.scoreDocs;for(ScoreDoc scoreDoc : scoreDocs){//获取docIDint docID = scoreDoc.doc;//通过文档ID从硬盘中读取出对应的文档Document document = indexReader.document(docID);//get域名可以取出值 打印System.out.println("fileName:" + document.get("fileName"));System.out.println("fileSize:" + document.get("fileSize"));System.out.println("============================================================");}}}
- lucene初体验
- Lucene初体验
- Lucene初体验
- lucene初体验
- Lucene 初体验
- lucene全文检索初体验-lucene demo演示
- 全文检索引擎工具包Lucene初体验
- Lucene一(开篇:lucene整体学习路线和初体验)
- 搜索学习入门--Lucene初体验(Lucene索引的增删改查)
- Lucene全文检索入门体验
- 全文信息检索lucene框架深度体验
- 用lucene做搜索引擎的体验
- 初体验
- 初体验
- 初体验
- 初体验
- 初体验
- 初体验
- 优先队列的基本用法(初步)
- angular中使用bootstrap-multiselect设置单选选中
- 实时对战网络游戏--基于帧同步的最佳实践
- React Native项目修改包名
- 基于Spring Boot和Spring Cloud实现微服务架构学习(四)-Spring Cloud总结
- lucene初体验
- 练习题 No.20 食物链
- 5-69 查验身份证 (15分)
- [jvm]JVM内存模型
- 这些轻松赚钱的方法,学会就能月入上万
- 关于如何实现在整合struts2和hibernate4框架下实现many-to-one级联数据表在JSP页面中的输出
- 网络基础:NetBIOS
- java中char和int类型的相互转换
- GetInvocationList