Lucene学习-2

全文索引

任何技术都有一些核心,全文搜索也有核心,而它的核心分为:索引创建,索引搜索。

  • 索引创建

将现实世界中所有的结构化和非结构化数据提取信息,创建索引的过程。
那么索引里面究竟存的什么,以及如何创建索引呢?在这通过下面的例子来解答这个问题。
首先构造三个不同的句子,有长有短:
在这里插入图片描述
在①处分别为3个句子加上编号,然后进行分词,把被一个单词分解出来与编号对应放在②处;在搜索的过程总,对于搜索的过程中大写和小写指的都是同一个单词,在这就没有区分的必要,按规则统一变为小写放在③处;要加快搜索速度,就必须保证这些单词的排列时有一定规则,这里按照字母顺序排列后放在④处;最后再简化索引,合并相同的单词,就得到如下结果:
在这里插入图片描述
通常在数据库中我们都是根据文档找到内容,而这里是通过词,能够快速找到包含他的文档,这就是文档倒排链表。

  • 索引搜索

就是得到用户的查询请求,搜索创建的索引,然后返回结果的过程。
在这里插入图片描述
比如我们要搜索java world两个关键词,符合java的有1,2两个文档,符合world的有1,3两个文档,在搜索引擎中直接这样排列两个词他们之间是OR的关系,出现其中一个都可以被找到,所以这里3个都会出来。全文检索中是有相关性排序的,那么结果在是怎么排列的呢?hello java world中包含两个关键字排在第一,另两个都包含一个关键字,得到结果,hello lucene world排在第二,java在最长的句子中占的权重最低排在结果集的第三。从这里可以看出相关度排序还是有一定规则的。

Lucene入门

Lucene是什么
Apache Lucene是一个用Java写的高性能、可伸缩的全文检索引擎工具包,它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能。Lucene的目标是为各种中小型应用程序加入全文检索功能。
Lucene的核心作者:Doug Cutting是一位资深全文索引/检索专家。
版本发布情况:2000年3月,最初版发布;2001年9月,加入apache;2004年7月,发布1.4正式版;2009年11月,发布2.9.1(jdk1.4)及3.0(jdk1.5)版本;2015年3月,发布4.10.4。2016年2月,发布5.5.0。
Helloworld
Lucene的索引库和数据库一样,都提供相应的API来便捷操作。
在这里插入图片描述
Lucene中的索引维护使用IndexWriter,由这个类提供添删改相关的操作;索引的搜索则是使用IndexSearcher进行索引的搜索。HelloWorld代码如下。
创建索引:

/**	
步骤:
1、 把文本内容转换为Document对象
   文本是作为Document对象的一个字段而存在
2、准备IndexWriter(索引写入器)
3 、通过IndexWriter,把Document添加到缓冲区并提交
     addDocument
     commit
     close
*/   
... 
//创建索引的数据 现在写死,以后根据实际应用场景
String doc1 = "hello world";
String doc2 = "hello java world";
String doc3 = "hello lucene world";
private String path ="F:/eclipse/workspace/lucene/index/hello";
...
@Test
public void testCreate() {
	try {
		//2、准备IndexWriter(索引写入器)
		//索引库的位置 FS fileSystem
		Directory d = FSDirectory.open(Paths.get(path ));
		//分词器
		Analyzer analyzer = new StandardAnalyzer();
		//索引写入器的配置对象
		IndexWriterConfig conf = new IndexWriterConfig(analyzer);
		IndexWriter indexWriter = new IndexWriter(d, conf);
		System.out.println(indexWriter);
		
		//1、 把文本内容转换为Document对象
		//把文本转换为document对象
		Document document1 = new Document();
		//标题字段
		document1.add(new TextField("title", "doc1", Store.YES));
		document1.add(new TextField("content", doc1, Store.YES));
		//添加document到缓冲区
		indexWriter.addDocument(document1);
		Document document2 = new Document();
		//标题字段
		document2.add(new TextField("title", "doc2", Store.YES));
		document2.add(new TextField("content", doc2, Store.YES));
		//添加document到缓冲区
		indexWriter.addDocument(document2);
		Document document3 = new Document();
		//标题字段
		document3.add(new TextField("title", "doc3", Store.YES));
		document3.add(new TextField("content", doc3, Store.YES));
		
		//3 、通过IndexWriter,把Document添加到缓冲区并提交
		//添加document到缓冲区
		indexWriter.addDocument(document3);
		indexWriter.commit();
		indexWriter.close();
	} catch (Exception e) {
		e.printStackTrace();
	}
	...
}

搜索索引:

/**	
1 封装查询提交为查询对象
2 准备IndexSearcher 
3 使用IndexSearcher传入查询对象做查询-----查询出来只是文档编号DocID
4 通过IndexSearcher传入DocID获取文档
5 把文档转换为前台需要的对象 Docment---->  Article
*/   
@Test
public void testSearch() {
	String keyWord = "lucene";
	try {
		// * 1 封装查询提交为查询对象
	    //通过查询解析器解析一个字符串为查询对象
		String f = "content"; //查询的默认字段名,
		Analyzer a = new StandardAnalyzer();//查询关键字要分词,所有需要分词器
		QueryParser parser = new QueryParser(f, a);
		Query query = parser.parse("content:"+keyWord);
		// * 2 准备IndexSearcher
		Directory d = FSDirectory.open(Paths.get(path ));
		IndexReader r = DirectoryReader.open(d);
		IndexSearcher searcher = new IndexSearcher(r);
		// * 3 使用IndexSearcher传入查询对象做查询-----查询出来只是文档编号DocID
		TopDocs topDocs = searcher.search(query, 1000);//查询ton条记录 前多少条记录
		System.out.println("总命中数:"+topDocs.totalHits);
		ScoreDoc[] scoreDocs = topDocs.scoreDocs;//命中的所有的文档的封装(docId)
		// * 4 通过IndexSearcher传入DocID获取文档
		for (ScoreDoc scoreDoc : scoreDocs) {
			int docId = scoreDoc.doc;
			Document document = searcher.doc(docId);
			// * 5 把文档转换为前台需要的对象 Docment----> Article
			System.out.println("=======================================");
			System.out.println("title:"+document.get("title")
							+",content:"+document.get("content"));
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

Lucence中索引操作的核心对象是IndexWriter和IndexReader和indexSearch

猜你喜欢

转载自blog.csdn.net/PZ_eng/article/details/91975963