lucene思维导图,让搜索引擎不再难懂

 今天,我们来讲讲lucene,同学们搬好板凳坐好啦。

(lucene干嘛的呀?)

首先我们来看张思维导图:

以上是我们java常用的全文搜索引擎框架,很多项目的搜索功能都是基于以上4个框架完成的。

所以lucene到底是干啥的?

Lucene是一套用于全文检索和搜索的开放源代码程序库,一个能够轻松集添加搜索功能到一个应用程序中的简单却强大的核心代码库和API。

Lucene,目前最受欢迎的Java全文搜索框架。原因很简单,hibernate search、solr、elasticsearch都是基于lucene拓展出来的搜索引擎。

Hibernate Search是在apache Lucene的基础上建立的主要用于Hibernate的持久化模型的全文检索工具。

Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

Solr它是一种开放源码的、基于 Lucene Java 的搜索服务器,易于加入到 Web 应用程序中。提供了层面搜索(就是统计)、命中醒目显示并且支持多种输出格式(包括XML/XSLT 和JSON等格式)。

所以lucene牛不牛逼!!

接下来,我们分为以下几个部分去理解、打开lucene的真面目。

  • 相关概念

  • 构建索引与查询索引过程

  • 倒排索引

  • 可视化工具

  • 项目应用指南

相关概念

lucene官方网站:http://lucene.apache.org/

既然是全文搜索工具,肯定有一定的排序结构和规则。当我们输入关键字的时候,lucene能安装内部的层次结构快速检索出我需要的内容。这里面会涉及到几个层次和概念。

索引库(Index)

一个目录一个索引库,同一文件夹中的所有的文件构成一个Lucene索引库。类似数据库的表的概念。

(lucene的索引实例)

段(Segment)

Lucene索引可能由多个子索引组成,这些子索引成为段。每一段都是完整独立的索引,能被搜索。

文档(Document)

一个索引可以包含多个段,段与段之间是独立的,添加新文档可以生成新的段,不同的段可以合并。段是索引数据存储的单元。类似数据库内的行或者文档数据库内的文档的概念。

域(Field)

一篇文档包含不同类型的信息,可以分开索引,比如标题,时间,正文,作者等。类似于数据库表中的字段

词(Term)

词是索引的最小单位,是经过词法分析和语言处理后的字符串。一个Field由一个或多个Term组成。比如标题内容是“hello lucene”,经过分词之后就是“hello”,“lucene”,这两个单词就是Term的内容信息,当关键字搜索“hello”或者“lucene”的时候这个标题就会被搜索出来。

分词器(Analyzer)

一段有意义的文字需要通过Analyzer来分割成一个个词语后才能按关键词搜索。StandartdAnalyzer是Lucene中常用的分析器,中文分词有CJKAnalyzer、SmartChinieseAnalyzer等。

(lucene 索引存储结构概念图)

上图大概可以这样理解,索引内部由多个段组成,当新文档添加进来时候会生成新的段,不同的段之间可以合并(Segment-0、Segment-1、Segment-2合并成Segment-4),段内含有文档号与文档的索引信息。而每个文档内有多个域可以进行索引,每个域可以指定不同类型(StringField,TextField)。

所以,从图中可以看出,lucene的层次结构依次如下:索引(Index) –> 段(segment) –> 文档(Document) –> 域(Field) –> 词(Term)

在上面我们了解了lucene的一些基本概念,接下来我们进入原理分析的环节。

(为什么lucene搜索引擎查询这么快?)

倒排索引

我们都知道要想提高检索速度要建立索引,重点就在这里,lucene使用了倒排索引(也叫反向索引)的结构。

倒排索引(反向索引)自然就有正排索引(正向索引)。

  • 正排索引是指从文档检索出单词,正常查询的话我们都是从文档里面去检索有没这个关键字单词。

  • 倒排索引是指从单词检索出文档,与从正排索引是倒过来的概念,需要预先为文档准备关键字,然后查询时候直接匹配关键字得到对应的文档。

有一句这样的总结:由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。

(具体怎么实现的呀?)

咱们来举个例子来研究一下(例子来源于网络):

假如现在有两个文档,内容分别是:

  • 文档1:home sales rise in July.

  • 文档2:increase in home sales in July.     

分析上图可知,首先文档经过分词器(Analyzer)分词之后,我们可以得到词(term),词和文档ID是对应起来的,接下来这些词集进行一次排序,然后合并相同的词并统计出现频率,以及记录出现的文档ID。

所以:

实现时,lucene将上面三列分别作为词典文件(Term Dictionary)频率文件(frequencies)、位置文件 (positions)保存。其中词典文件不仅保存有每个关键词,还保留了指向频率文件和位置文件的指针,通过指针可以找到该关键字的频率信息和位置信息。 

索引时,假设要查询单词 “sales”,lucene先对词典二元查找、找到该词,通过指向频率文件的指针读出所有文章号,然后返回结果。词典通常非常小,因而,整个过程的时间是毫秒级的。  

(原来如此!)

lucene可视化工具Luke

  • https://github.com/DmitryKey/luke/releases

构建索引与查询索引过程

以上我们知道了lucene构建索引的原理,接下来我们在代码层面去使用lucene。

我们先来看一张图:

检索文件之前先要建立索引,所以上图得从“待检索文件”节点开始看。

构建索引过程:

1、为每一个待检索的文件构建Document类对象,将文件中各部分内容作为Field类对象。

2、使用Analyzer类实现对文档中的自然语言文本进行分词处理,并使用IndexWriter类构建索引。

3、使用FSDirectory类设定索引存储的方式和位置,实现索引的存储。

检索索引过程:

4、使用IndexReader类读取索引。

5、使用Term类表示用户所查找的关键字以及关键字所在的字段,使用QueryParser类表示用户的查询条件。

6、使用IndexSearcher类检索索引,返回符合查询条件的Document类对象。

其中虚线指向的是这个类所在的包名(package)。如Analyzer在org.apache.lucene.analysis包下。

构建索引代码:

//创建索引
public class CreateTest {

    public static void main(String[] args) throws Exception {
        Path indexPath = FileSystems.getDefault().getPath("d:\\index\\");

//        FSDirectory有三个主要的子类,open方法会根据系统环境自动挑选最合适的子类创建
//        MMapDirectory:Linux, MacOSX, Solaris
//        NIOFSDirectory:other non-Windows JREs
//        SimpleFSDirectory:other JREs on Windows
        Directory dir = FSDirectory.open(indexPath);

        // 分词器
        Analyzer analyzer = new StandardAnalyzer();
        boolean create = true;
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);
        if (create) {
            indexWriterConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE);
        } else {
            // lucene是不支持更新的,这里仅仅是删除旧索引,然后创建新索引
            indexWriterConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
        }
        IndexWriter indexWriter = new IndexWriter(dir, indexWriterConfig);

        Document doc = new Document();
        // 域值会被索引,但是不会被分词,即被当作一个完整的token处理,一般用在“国家”或者“ID
        // Field.Store表示是否在索引中存储原始的域值
        // 如果想在查询结果里显示域值,则需要对其进行存储
        // 如果内容太大并且不需要显示域值(整篇文章内容),则不适合存储到索引中
        doc.add(new StringField("Title", "sean", Field.Store.YES));
        long time = new Date().getTime();
        // LongPoint并不存储域值
        doc.add(new LongPoint("LastModified", time));
//        doc.add(new NumericDocValuesField("LastModified", time));
        // 会自动被索引和分词的字段,一般被用在文章的正文部分
        doc.add(new TextField("Content", "this is a test of sean", Field.Store.NO));

        List<Document> docs = new LinkedList<>();
        docs.add(doc);

        indexWriter.addDocuments(docs);
        // 默认会在关闭前提交
        indexWriter.close();
    }
}

对应时序图:

查询索引代码:

//查询索引
public class QueryTest {

    public static void main(String[] args) throws Exception {
        Path indexPath = FileSystems.getDefault().getPath("d:\\index\\");
        Directory dir = FSDirectory.open(indexPath);
        // 分词器
        Analyzer analyzer = new StandardAnalyzer();

        IndexReader reader = DirectoryReader.open(dir);
        IndexSearcher searcher = new IndexSearcher(reader);

        // 同时查询多个域
//        String[] queryFields = {"Title", "Content", "LastModified"};
//        QueryParser parser = new MultiFieldQueryParser(queryFields, analyzer);
//        Query query = parser.parse("sean");

        // 一个域按词查doc
//        Term term = new Term("Title", "test");
//        Query query = new TermQuery(term);

        // 模糊查询
//        Term term = new Term("Title", "se*");
//        WildcardQuery query = new WildcardQuery(term);

        // 范围查询
        Query query1 = LongPoint.newRangeQuery("LastModified", 1L, 1637069693000L);

        // 多关键字查询,必须指定slop(key的存储方式)
        PhraseQuery.Builder phraseQueryBuilder = new PhraseQuery.Builder();
        phraseQueryBuilder.add(new Term("Content", "test"));
        phraseQueryBuilder.add(new Term("Content", "sean"));
        phraseQueryBuilder.setSlop(10);
        PhraseQuery query2 = phraseQueryBuilder.build();

        // 复合查询
        BooleanQuery.Builder booleanQueryBuildr = new BooleanQuery.Builder();
        booleanQueryBuildr.add(query1, BooleanClause.Occur.MUST);
        booleanQueryBuildr.add(query2, BooleanClause.Occur.MUST);
        BooleanQuery query = booleanQueryBuildr.build();

        // 返回doc排序
        // 排序域必须存在,否则会报错
        Sort sort = new Sort();
        SortField sortField = new SortField("Title", SortField.Type.SCORE);
        sort.setSort(sortField);

        TopDocs topDocs = searcher.search(query, 10, sort);
        if(topDocs.totalHits > 0)
            for(ScoreDoc scoreDoc : topDocs.scoreDocs){
                int docNum = scoreDoc.doc;
                Document doc = searcher.doc(docNum);
                System.out.println(doc.toString());
            }
    }
}

对应时序图:

lucene版本信息:

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-core</artifactId>
    <version>7.4.0</version>
</dependency>

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-queryparser</artifactId>
    <version>7.4.0</version>
</dependency>

项目应用指南

在实际开发,比较少会直接用lucene,现在主流的搜索框架solr、Elasticsearch都是基于lucene,给我们提供了更加简便的API。特别是在分布式环境中,Elasticsearch可以问我们解决单点问题、备份问题、集群分片等问题,更加符合发展趋势。

搜索引擎(一)体系结构 思维导图
sndnyangd的专栏
08-04 2095
搜索引擎体系结构概述        思维导图 http://www.xmind.net/share/sndnyangd/search-engine-architecture-1/           看的是清华大学和百度合作的搜索引擎基础课程的教材《搜索引擎技术基础》,这里写的是第四章——搜索体系结构概述,截图在这儿也放不下,千言万语也不如一张图,所以,就用这种方式来写吧。        之
lucene可视化工具 Luck-6.5.0
11-26
lucene的可视化工具,luck,能够将lucene中的数据显示在luck工具上
Lucene/Solr/Elasticsearch可视化工具luke的下载及使用
yue
03-22 4089
luke的下载及使用
Luke 5—— 可视化 Lucene 索引查看工具,可以查看ES的索引
djph26741的博客
02-23 432
Luke 5 发布,可视化 Lucene 索引查看工具 oschina发布于2015年08月31日 这是一个主要版本,该版本支持 Lucene 5.2.0。它支持 elasticsearch 1.6.0(Lucene的4.10.4)已解决的问题:#20增加支持重建索引并不会存储领域,不暴露位置的字段值。Pull Requests:#23 Elasticsearch 支持...
【第七章·查找技术】思维导图
メメメ
12-29 583
Java搜索引擎 Lucene
06-06
Java搜索引擎 Lucene
搜索引擎开发现实文档(lucene)
09-30
搜索引擎开发现实文档(lucene)
java 基于lucene的gis搜索引擎可用于shp文件
07-31
java 基于lucene的gis搜索引擎可用于shp文件,将shp文件转换为索引文件,提高了搜索效率,同样支持空间查询,属性过滤等,gis开发人员便捷式开发,不用写代码,将shp文件放入指定位置即可
Lucene+Heritrix(搜索引擎开发)
07-01
Lucene+Heritrix(搜索引擎与信息检索),Lucene+Heritrix(搜索引擎与信息检索)
lucene 自定义合并策略_lucene/BooleanQuery倒排表合并策略.md at master · chakra-coder/lucene · GitHub...
weixin_31174767的博客
01-13 177
Lucene中基本的Query类型有以下几种:TermQuery,WildcardQuery,PhraseQuery,PrefixQuery,MultiPhraseQuery,FuzzyQuery,RegexpQuery,TermRangeQuery,NumericRangeQuery,ConstantScoreQuery,DisjunctionMaxQuery,MatchAllDocsQuery...
搜索引擎工作原理
02-25
搜索引擎工作原理,搜索引擎工作原理思维导图
Lucene 索引与检索架构图
Zoe_Liu2016的博客
03-05 201
在基于单词的检索方法中,同义词会降低检索算法的召回率(Recall),而多义词的存在会降低检索系统的准确率(Precision)。 转载于:https://www.cnblogs.com/jetHu/p/8510479.html...
lucene案例demo
Buggggggg
04-27 202
1.github代码 https://github.com/mx342/luceneDemo 2.demo代码 import org.apache.commons.io.FileUtils; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAna...
Lucene的总体架构
走向程序的康庄大道
02-12 388
Lucene in action中,Lucene 的构架和过程如下图,让我们更细一些看Lucene的各组件:那么如何应用这些组件呢?让我们再详细到对Lucene API 的调用实现索引和搜索过程。以上便是Lucene API函数的简单调用。然而当进入Lucene的源代码后,发现Lucene有很多包,关系错综复杂。然而通过下图,我们不难发现,Lucene的各源码模块,都是对普通索引和搜索过程的一种...
Lucene总结二:Lucene的总体架构
haohaizi的博客
05-31 497
如下技术文章也是从我之前很久开的csdn账号上面迁移过来的 Lucene总的来说是: 一个高效的,可扩展的,全文检索库。 全部用Java实现,无须配置。 仅支持纯文本文件的索引(Indexing)和搜索(Search)。 不负责由其他格式的文件抽取纯文本文件,或从网络中抓取文件的过程。 在Lucene in action中,Lucene 的构架和过程如下图, 说明Lucene是有索引和搜索的两个过程,包含索引创建,索引,搜索三个要点。 让我们更细一些看Lucene的各组件: 被索引的
使用Lucene在知识图谱上构建索引
魔图互联
09-04 1174
这篇文章讲讲如何在知识图谱数据集上构建索引进行查询。倒排索引是一种数据结构,它表示了这样一种映射,以字或词或数字为关键字进行索引,映射到出现这个字或词的所有文档或者数据库...
全文检索工具Lucene入门教程
AlbertYang的博客
07-11 7652
1.什么是Lucene Apache Lucene是完全用Java编写的高性能,功能齐全的,全文检索引擎工具包,通过lucene可以让程序员快速开发一个全文检索功能。 1.1什么是全文检索 在我们的生活中数据总体分为两种:结构化数据 和非结构化数据 。 结构化数据: 指具有固定格式或有限长度的数据,如数据库,元数据等。 非结构化数据: 指不定长或无固定格式的数据,如邮件,word文档等。非结构化数据又叫全文数据。 当然有的地方还会提到第三种,半结构化数据,如XML,HTML等,半结构化数据可以.
lucene 思维导图
彻底拆分,一切可控!
03-28 1006
apache lucene 一个最简单的实例
墨竹
04-06 618
就像每个程序都有一个Hello World来让人体验它一样,lucene也可以很简单的提供一个实例。如下(来自lucene in action的例子)有两个类组成: 一个是建立索引:package my;import java.io.File; import java.io.FileReader; import java.io.IOException; import java.ut
基于lucene全文搜索引擎
最新发布
01-09
lucene是一个开源的全文搜索引擎库,它提供了丰富的API和功能,能够帮助用户进行高效的文本检索。基于lucene全文搜索引擎,用户可以创建自己的搜索引擎应用程序,用于对大量的文本数据进行搜索和索引。 使用lucene...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 关于Excel保存为csv文件时提示“可能含有与CSV(逗号分隔)不兼容的功能” 71531
  • 无法连接远程桌面--必须为远程桌面启用Windows防火墙例外 49096
  • 理解serialVersionUID是什么?有什么用?如何生成? 33784
  • RedisInsight :Redis 官方可视化工具来啦 24955
  • MySQL经典100问 24919

分类专栏

  • 运维监控 2篇
  • 项目管理 2篇
  • 搜索引擎 - 实战篇 22篇
  • 搜索引擎 - 架构 & 原理篇 16篇
  • 搜索排序引擎 - 行业方案 17篇
  • 质量保障 4篇
  • 算法模型 - 基础篇 4篇
  • 算法模型 - 高阶篇 4篇
  • 大数据 10篇
  • 工程算法 7篇
  • 数据结构 5篇
  • 任务调度 2篇
  • Java基础 32篇
  • DevOps 14篇
  • Linux 实战 & 底层机制 & 原理 18篇
  • 并发编程 11篇
  • 关系型数据库 58篇
  • Spring & SpringBoot 11篇
  • 分布式缓存 - Redis 56篇
  • 消息中心组件 - kafka 33篇
  • 消息中心组件 - mq 17篇
  • 数据访问 & 同步组件 2篇
  • 微服务 9篇
  • 问题排查 7篇
  • 性能优化 2篇
  • 工具插件 8篇
  • 架构设计 35篇
  • 计算机硬件 & 网络 & 安全认证 28篇
  • 应用实战 9篇
  • 技术管理 3篇
  • 前端部分 3篇

最新评论

  • Java 创建对象的 6 种方式,总有一种适合你

    罗同学笔记: 类加载器应该也算一种吧。classLoader.loadClass("")然后再newInstance();这个和Class.forName("")的区别在于 // 1 Class.forName 调用该类的静态代码块 // 2 classLoader.loadClass 不会调用该类的静态方法 不知道我有没有理解错

  • 5种限流算法,7种限流方式,挡住突发流量

    年少一去不复返: 清理过期的数据老数据的这个是不是写错了,应该是 if (!treeMap.isEmpty() && (now - treeMap.firstKey()) > claerTime) {

  • 超快速定位OOM(内存溢出问题)

    weixin_46800139: 博主您好,请问元空间使用的不也是直接内存吗,直接内存oom一般由哪些因素引起的

  • 图解Word2vec,读这一篇就够了(通俗易懂)

    m0_74247322: qpzfl

  • 八张动图搞懂代理和反向代理

    PaiMeng2028: 当老师去吧哥

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • springboot如何把HttpServletRequest传入到controller
  • 移动端iphone抓包调试神器—Stream安装和使用(一)
  • springboot项目配置动态注入与springboot读取docker环境变量
2023年3篇
2022年431篇
2015年1篇
2014年7篇
2013年49篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

深圳SEO优化公司清徐网站优化按天扣费多少钱娄底网站优化推广报价莱芜SEO按效果付费公司迁安SEO按效果付费红河SEO按天收费哪家好观澜SEO按天扣费哪家好松原网站推广工具公司天水百搜标王价格石家庄网站改版白银网站优化排名推荐长葛百度关键词包年推广公司绍兴网站关键词优化平湖百姓网标王推广公司武汉网站优化按天收费报价鞍山关键词按天扣费推荐云浮网站推广方案价格诸城建站哪家好文山SEO按天扣费报价怀化网站优化排名多少钱保山百姓网标王推广南平网站搜索优化报价咸宁网站优化按天收费推荐绵阳英文网站建设报价湛江关键词按天扣费公司杭州SEO按天收费价格广州网站优化按天计费哪家好洛阳网站推广焦作SEO按效果付费仙桃百度网站优化廊坊SEO按效果付费哪家好歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化