博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lucene(1)---入门示例
阅读量:4089 次
发布时间:2019-05-25

本文共 4773 字,大约阅读时间需要 15 分钟。

1、什么是Lucene?

Lucene是一个基于java的全文信息检索工具包,为应用程序提供索引和搜索功能。

2、为什么需要使用Lucene?

如果没有使用Lucene,需要根据关键字搜索数据库表中的记录,就需要使用like一个字符一个字符

的去匹配,这样子查询对数据库的性能开销十分大。

2)、当数据量非常大时,会造成系统中查询效率低下,使用lucene可以减少数据库性能开销,提升查询效率。

3、Lucene中常用概念

1)、Docuement:用于对需要进行索引的文档进行描述

2)、Field:用于对document进行描述

3)、Analyzer:对需要进行索引的document来说,需要按照一定的规则将内容进行切分,这样才能被索引

    analyzer就是用于切词

4)、indexWriter:它是document和索引之间的桥梁,用于将document加载到索引中

5)、Directory:用于描述索引的存放位置

6)、Query:用于将需要查询的内容封装成索引能够理解的内容

7)、IndexSearch:用来根据Query在索引中检索复合条件的内容

4、Lucene的执行流程

Lucene的操作方式和数据库有点类似,索引使用Lucene就要先创建数据库,然后往这个数据表中一行

一行的插入数据,数据插入成功之后,就可以操作这张数据表,实现CRUD操作。

1)、创建索引文件目录,然后将需要检索的信息用Field对应匹配的封装成一个Doocument文档对象

         将这个对象放入索引文件目录中,这里既可以将索引放入内存中,也可以放入磁盘中

2)、如果发现信息有问题需要删除,那么索引文件也要删除。否则检索的时候还是会查询得到,这个

         时候需要根据索引id去删除对应的索引

3)、如果发现信息被更新,那么索引文件也要更新,这个时候需要先将旧的索引删除然后添加新的索引。

4)、全文检索和查询数据库一样,先需要创建索引读取对象,然后封装Query查询对象,

 调用search()方法得到检索结果

5、使用Lucene将索引写入内存中

1)、创建内存目录对象RAMDirectory

Directory directory=new RAMDirectory();

DirectoryReader reader=DirectoryReader.open(directory);

2)、创建索引写入器IndexWriter

IndexWriterConfig writerConfig=new IndexWriterConfig(luceneVersion, new StandardAnalyzer()); IndexWriter writer = new IndexWriter(directory, writerConfig);  //将
3)、创建Document文档对象

在lucene中创建的索引可以看做是数据库中的一张表,表中可以有字段

往表里面添加内容可以根据字段去匹配查询

Document document=new Document();

往document文档对象添加内容

document.add(new StringField("name","Tom",Field.Store.YES));

4)、用索引写入器将指定的数据存入内存目录对象中

indexWriter.addDocument(document);

5)、创建索引查询对象IndexSearcher,里面传递的是写入的内存目录对象

创建DirectoryReader:

DirectoryReader reader=DirectoryReader.open(directory);

IndexSearcher searcher = new IndexSearcher(reader);
6)、将关键字封装成Query查询对象

Query query = new TermQuery(new Term("name", "Chenghui"));
7)、将查询的结果返回个TopDocs,然后遍历里面索引的Document对象,显示查询结果

TopDocs rs = searcher.search(query, null, 10);

for (int i = 0; i < rs.scoreDocs.length; i++) {        // rs.scoreDocs[i].doc 是获取索引中的标志位id, 从0开始记录       Document firstHit = searcher.doc(rs.scoreDocs[i].doc);       System.out.println("name:" + firstHit.getField("name").stringValue());       System.out.println("sex:" + firstHit.getField("sex").stringValue());  	            }

8)、关闭IndexWriter写入器、关闭RAMDirectory目录对象

indexWriter.close();

ramDirectory.close();

将索引写入内存中,并查询索引示例代码如下:

package com.cn.test;import java.io.IOException;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.index.DirectoryReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.index.Term;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.Query;import org.apache.lucene.search.TermQuery;import org.apache.lucene.search.TopDocs;import org.apache.lucene.store.RAMDirectory;import org.apache.lucene.util.Version;/** * 将索引写入内存中,并查询内存中索引 * */public class Test {	//当前使用lucene版本	private static Version luceneVersion=Version.LUCENE_4_10_1;	private RAMDirectory ramDirectory=null;	private static TopDocs topDocs=null;	/**	 * 创建索引	 * @throws IOException 	 * */	public void createIndex() throws IOException{		//1、创建内存目录对象,内存目录对象用于存放索引的位置		ramDirectory=new RAMDirectory();		//2.创建索引写入器IndexWriter,用于将document加载到索引中		//2.1、创建切词对象,对于需要进行索引的document来说,需要按照一定的规则将内容进行切分		Analyzer analyzer=new StandardAnalyzer();		IndexWriterConfig writerConfig=new IndexWriterConfig(luceneVersion,analyzer);		IndexWriter indexWriter=new IndexWriter(ramDirectory, writerConfig);		//3.创建document对象,用于对需要进行索引的文档进行描述		Document document=new Document();		/**      	 *	4.下面为document对象添加三个字段     	 *  document.add(field),field是需要被索引的字段     	 *  StringField将字符串当做一个整体,不可被切分     	 *  TextField中的字符串可以被切分     	 *  new StringField(name,value,stored)     	 *  name:字段名称     	 *  value:字段的值     	 *  Field.Store.YES:将字段值进行存储(存储的是未分词的字段值)     	 *  Field.Store.NO:不存储字段值(存储与索引没有关系)		 * */		document.add(new StringField("username", "Tom", Field.Store.YES));		document.add(new StringField("message","this is a program!",Field.Store.YES));		document.add(new StringField("doSomthing", "I am learning lucene!", Field.Store.YES));		//5、用索引写入器将需要索引的文档对象加入		indexWriter.addDocument(document);		//6.将索引写入器关闭		indexWriter.close();	}	/**	 * 查询索引	 * @throws IOException 	 * */	public void searchIndex() throws IOException{		//1.创建DirectoryReader流,用于读取directory		DirectoryReader directoryReader=DirectoryReader.open(ramDirectory);		//2.创建IndexSearcher检索索引的对象		IndexSearcher indexSearcher=new IndexSearcher(directoryReader);		//3.创建Query查询对象,根据需要搜索的关键字封装成一个Term组合对象		Query query=new TermQuery(new Term("message","this is a program!"));		//4.去索引目录中查询,返回的是TopDocs对象,里面存放的就是Document文档对象		topDocs=indexSearcher.search(query, null, 10);				for(int i=0;i

转载地址:http://vquii.baihongyu.com/

你可能感兴趣的文章
PX4+激光雷达在gazebo中仿真实现(古月居)
查看>>
专业和业余的区别就在于你在基础在基本功打磨练习花的时间
查看>>
通过mavlink实现自主航线的过程笔记
查看>>
Ardupilot飞控Mavlink代码学习
查看>>
这些网站有一些嵌入式面试题合集
查看>>
我觉得刷题是有必要的,不然小心实际被问的时候懵逼,我觉得你需要刷个50份面试题。跟考研数学疯狂刷卷子一样!
查看>>
我觉得嵌入式面试三要素:基础吃透+项目+大量刷题,缺一不可。不刷题是不行的。而且得是大量刷,刷出感觉套路,别人做题都做得是固定题型套路条件反射了,你还在那慢慢理解慢慢推是不行的,也是考研的教训。
查看>>
相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像。
查看>>
现在来看,做个普罗米修斯的docker镜像对我而言并不难,对PX4仿真环境配置也熟悉了。
查看>>
删除docker容器和镜像的命令
查看>>
VINS-Fusion Intel® RealSense™ Depth Camera D435i
查看>>
使用Realsense D435i运行VINS-Fusion并建图
查看>>
gazebo似乎就是在装ROS的时候一起装了,装ROS的时候选择的是ros-melodic-desktop-full的话。
查看>>
React + TypeScript 实现泛型组件
查看>>
TypeScript 完全手册
查看>>
React Native之原理浅析
查看>>
Git操作清单
查看>>
基础算法
查看>>
前端面试
查看>>
React Hooks 异步操作踩坑记
查看>>