【ElasticSearch从入门到放弃系列 三】Lucene的基本概念和使用(上)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 【ElasticSearch从入门到放弃系列 三】Lucene的基本概念和使用(上)

上一篇blog介绍了全文检索的实现思路,这一篇呢主要介绍开源的搜索引擎Lucene是如何基于这样的思路来进行具体的实现的。

Lucene基本概念

Lucene是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。在Java开发环境里Lucene是一个成熟的免费开源工具。一句话概括,就是一组实现全文检索的Jar包

Lucene环境搭建

首先需要从官网 下载Lucene,Java需要1.8以上的版本支持,,内容组成如下,实际上我们这里用到的就是以下的5个jar包:

其中commons-io是为了进行文件的读写,junit是为了进行单元测试。首先我们提供如下待检索文件:

然后使用lucene建立倒排索引,来通过关键字快速检索文档。按照上一篇blog提到的需求我们来做一下。

索引的基本使用

接下来我们看看如何创建索引、查询索引,完成全流程

创建索引

创建一个java工程,并导入jar包:

Field的几个属性

创建Field的时候,有几种重载方法可以选择:其实string就是索引不分词、textfield就是索引分词

代码执行

然后在程序里读取文件转为lucene使用到的相关对象:

package com.company;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Test;
import java.io.File;
public class Main {
      //创建索引
    @Test
    public void createIndex() throws Exception {
        //创建indexwriter对象
        Directory directory = FSDirectory.open(new File("F:\\lucene-index").toPath());
        IndexWriterConfig config = new IndexWriterConfig();
        IndexWriter indexWriter = new IndexWriter(directory, config);
        //原始文档的路径
        File dir = new File("F:\\lucene-file");
        for (File f : dir.listFiles()) {
            String fileName = f.getName();
            String fileContent = FileUtils.readFileToString(f);
            String filePath = f.getPath();
            long fileSize  = FileUtils.sizeOf(f);
            //创建文件名域
            //第一个参数:域的名称
            //第二个参数:域的内容
            //第三个参数:是否存储
            //(分析、索引、存储)【索引分词存储】
            Field fileNameField = new TextField("filename", fileName, Field.Store.YES);
            //文件大小域(分析、索引、不存储)【索引分词不存储】
            Field fileSizeField = new LongPoint("size", fileSize);
            //文件路径域(不分析、索引、存储)【索引不分词存储】
            Field filePathField = new StringField("path", filePath, Field.Store.YES);
            //文件内容域(不分析、不索引、存储)【不索引不分词存储】
            Field fileContentField = new StoredField("content",fileContent);
            //创建document对象
            Document document = new Document();
            document.add(fileNameField);
            document.add(fileContentField);
            document.add(filePathField);
            document.add(fileSizeField);
            //创建索引,并写入索引库
            indexWriter.addDocument(document);
        }
        //关闭indexwriter
        indexWriter.close();
    }

创建完成后的索引文件夹查看:

显然是看不了的,所以需要使用工具去看,就是luke,一定要注意,luke的版本一定要和lucene一毛一样,否则就出问题了,例如我这里使用的都是7.4.0版本。打开luke可以看到每个域拆分的关键字:

以及可以看到所有的文档,如果有存储,对应域上会有数据:

查询索引

查询索引的代码内容如下所示:

//查询索引
    @Test
    public void searchIndex() throws Exception {
        //第一步:创建一个Directory对象,也就是索引库存放的位置。
        Directory directory = FSDirectory.open(new File("F:\\lucene-index").toPath());
        //第二步:创建一个indexReader对象,需要指定Directory对象。
        IndexReader indexReader= DirectoryReader.open(directory);
        //第三步:创建一个indexsearcher对象,需要指定IndexReader对象
        IndexSearcher indexSearcher=new IndexSearcher(indexReader);
        //第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
        TermQuery termQuery=new TermQuery(new Term("filename","丑"));
        //第五步:执行查询。
        TopDocs topDocs = indexSearcher.search(termQuery, 5); //查询参数和返回最大数
        System.out.println("总命中数为"+topDocs.totalHits); //实际总命中数,不被返回数限制,就是真实的命中数
        //第六步:返回查询结果。遍历查询结果并输出。
        for (ScoreDoc scoreDoc:topDocs.scoreDocs) {
            Document document = indexSearcher.doc(scoreDoc.doc);
            System.out.println(document.get("filename"));
            System.out.println(document.get("path"));
            System.out.println("-------------------------");
        }
        //第七步:关闭IndexReader对象
        indexReader.close();
    }

查询结果如下,共命中了两篇文档:

对于索引不分词的查询,只能输入全名,例如对路径查询,替换下terms:

//第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
TermQuery termQuery=new TermQuery(new Term("path","F:\\lucene-file\\tml一般帅.txt"));

只搜帅或者tml这些关键词是搜不出来的,因为对于path域没有分过词:

中文分词器的使用

Lucene标准的StandardAnalyzer只支持单个的中文字。例如:

所以,如果查询很丑一定是搜索不出来的,因为根本就还没索引到文档。

这个时候为了符合中国人的使用习惯,我们使用第三方的IK分词器。

首先需要把Jar包导入到项目中,然后需要注意hotword.dic和ext_stopword.dic文件的格式为UTF-8,注意是无BOM 的UTF-8 编码

调整下使用的分词器后,我们重建索引,写索引的时候使用IK分词器进行索引写入:

这个时候我们再看下分词效果,中文的词组就出来了。

那么为什么会这样呢?因为这些词都存在字典里,我们拿【很丑】举例:

然后我们再来跑一遍程序,看看查询的时候是分词是否生效:

这个时候搜【很丑】就能命中文件了。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
1月前
|
存储 Java API
Elasticsearch 7.8.0从入门到精通
这篇文章详细介绍了Elasticsearch 7.8.0的安装、核心概念(如正排索引和倒排索引)、RESTful风格、各种索引和文档操作、条件查询、聚合查询以及在Spring Boot中整合Elasticsearch的步骤和示例。
117 1
Elasticsearch 7.8.0从入门到精通
|
1月前
|
存储 分布式计算 大数据
大数据-169 Elasticsearch 索引使用 与 架构概念 增删改查
大数据-169 Elasticsearch 索引使用 与 架构概念 增删改查
57 3
|
2月前
|
数据可视化 Java Windows
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
本文介绍了如何在Windows环境下安装Elasticsearch(ES)、Elasticsearch Head可视化插件和Kibana,以及如何配置ES的跨域问题,确保Kibana能够连接到ES集群,并提供了安装过程中可能遇到的问题及其解决方案。
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
|
2月前
|
存储 关系型数据库 MySQL
浅谈Elasticsearch的入门与实践
本文主要围绕ES核心特性:分布式存储特性和分析检索能力,介绍了概念、原理与实践案例,希望让读者快速理解ES的核心特性与应用场景。
|
21天前
|
测试技术 API 开发工具
ElasticSearch核心概念:倒排索引
ElasticSearch核心概念:倒排索引
50 6
|
1月前
|
JSON 关系型数据库 API
ElasticSearch 的概念解析与使用方式(二)
ElasticSearch 的概念解析与使用方式(二)
25 1
|
1月前
|
存储 搜索推荐 Java
ElasticSearch 的概念解析与使用方式(一)
ElasticSearch 的概念解析与使用方式(一)
58 1
|
3月前
|
JSON 搜索推荐 数据挖掘
ElasticSearch的简单介绍与使用【入门篇】
这篇文章是Elasticsearch的入门介绍,涵盖了Elasticsearch的基本概念、特点、安装方法以及如何进行基本的数据操作,包括索引文档、查询、更新、删除和使用bulk API进行批量操作。
ElasticSearch的简单介绍与使用【入门篇】
|
2月前
|
JSON 监控 Java
Elasticsearch 入门:搭建高性能搜索集群
【9月更文第2天】Elasticsearch 是一个分布式的、RESTful 风格的搜索和分析引擎,基于 Apache Lucene 构建。它能够处理大量的数据,提供快速的搜索响应。本教程将指导你如何从零开始搭建一个基本的 Elasticsearch 集群,并演示如何进行简单的索引和查询操作。
209 3
|
3月前
|
存储 运维 搜索推荐
运维开发.索引引擎ElasticSearch.倒序索引的概念
运维开发.索引引擎ElasticSearch.倒序索引的概念
52 1