ElasticSearch——全文搜索引擎

一、为什么需要全文搜索引擎?

首先先来了解一个概念,在我们生活中一般来说有两种数据:结构化数据、非结构化数据

结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。
非结构化数据: 非结构化数据又可称为全文数据,指不定长或无固定格式的数据,如邮件,word文档等。

对于结构化数据我们可以直接从数据库查询,而对于非结构化的数据此时就要用到全文检索的方式查询,比如对一个文档或者网页中的内容文本每个词建立一个索引,把这些非结构化的变成结构化的方式然后来查询。

全文搜索引擎百度百科定义:全文搜索引擎是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。

简单理解:比如像淘宝、京东这种电商网站,商品的数据量很大很大,这些数据若存放在数据库中然后我们搜索是直接去数据库查询这样显然很不合理,因为一是查询慢,二是数据量大放数据库中存储需要空间。所以为了解决查询慢的问题,我们需要全文搜索引擎来去查询这些数据。

二、ElasticSearch概述

在介绍ElasticSearch之前,首先需要先了解lunece

Lucene:是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,lucene提供了查询引擎、索引引擎、部分文本分析引擎。

简单来说,lucene就是为我们开发人员提供了一些全文检索引擎工具包,我们调这些包里的方法就可以去实现全文搜索的功能了。(但其实直接去使用lucene来做也是很麻烦的,所以后面才有了类似solr、elasticsearch等这些搜索引擎

lucene是迄今为止最先进、性能最好、功能最全的搜索引擎,但是需要明白lucene只是一个库,lucene是java语言编写的,想要使用它就必须使用java作为开发语言来将其集成到我们的应用中,这就导致了有一定的局限性。再一个lucene非常复杂,如果直接来使用lucene那就需要深入了解它的底层工作原理,显然这个学习和使用成本太大了。

了解完lucene后再来看elasticsearch就很好理解了~

ElasticSearch:Elasticsearch是一个实时分布式搜索和分析引擎(注意,elasticsearch是一个真正的搜索引擎了),elasticsearch底层其实用到的就是lucene,它是对lucene的封装,从而对外留下一套简单的RestFul API,让我们更简单去实现我们所需要的全文搜索的功能。

Solr和Elasticsearch类似,都是基于Lucene的全文搜索引擎,solr的功能相较elasticsearch来说更多更广。
solr对已有的数据查询来说比elasticsearch要快,elasticsearch建立索引(也就是实时查询)比solr要快,因为solr建立索引时会产生io阻塞。

在2016年1月,ElasticSearch已超过Solr等,成为排名第一的搜索引擎类应用。

三、ElasticSearch安装

ElasticSearch是java语言编写的,此次安装的es版本是7.6.1,安装前需要确定jdk的版本最少是1.8以上,且配置好了jdk的环境变量。

官网下载: https://www.elastic.co/products/elasticsearch

  1. elasticsearch解压后就可用了,和tomcat类似,开箱即用
    在这里插入图片描述

  2. 进入bin目录,双击elasticsearch.bat启动
    在这里插入图片描述

  3. 浏览器输入localhost:9200得到以下信息,就表示安装成功!
    在这里插入图片描述

es安装好了,我们还需要一个可以查看es信息的图形化界面,不然怎么很直观去看es里面的索引啊文档啊这些信息呢?所以下一步要安装ES的图形化界面插件客户端

这个客户端就是一个基于node.js的一个前端项目(所以前提是一定要安装node.js的环境),从github上下载项目代码即可,

下载地址: https://github.com/mobz/elasticsearch-head/

  1. 下载后解压文件:
    在这里插入图片描述
  2. 解压之后安装依赖,在当前解压目录下打开cmd,输入cnpm install(安装一次即可,之后直接启动就行了)
  3. 启动项目,在当前目录的cmd下输入:npm run start
    在这里插入图片描述
  4. 浏览器输入http://localhost:9100 ,连接中输入elasticsearch的9200连接,连接成功,启动成功!
    在这里插入图片描述

注意:由于es和head客户端两个进程的端口号不同,所以存在跨域的问题,首次通过head客户端连接9200的es肯定连接不上,所以要在es的配置文件中增加如下配置:
在这里插入图片描述
#跨域配置
http.cors.enabled: true
http.cors.allow-origin: “*”

ELK 就是Elasticsearch、Logstash、Kibana,也被称为ElasticStack。Elasticsearch上面已经介绍过了,Logstash是ELK的中央数据流引擎,用于从不同目标(文件/数据存储/MQ)收集的不同格式数据,经过过滤后支持输出到不同目的地(文件/MQ/redis/elasticsearch/kafka等)

Kibana是一个针对ElasticSearch的开源分析及可视化平台,用来搜索、查看交互存储在ElasticSearch索引中的数据。和上面的那个head项目相比,kibana是一个更专业的查看分析数据的平台。

ELK在大数据中用到的比较多,有专业的ELK工程师这个岗位。

由于head项目作为es的图形化管理工具查看起来没有kibana专业,所以我们这里就再安装个kibana来认识一下kibana

安装kibana:

  1. 官网下载地址:https://www.elastic.co/cn/kibana,注意kibana版本要和es版本对应
  2. 下载完毕后解压即可,拆箱即用
    在这里插入图片描述
  3. kibana默认是英文版本的,可以改成中文的,在kibana.yml配置文件中加入一行配置:i18n.locale: “zh-CN” ,然后启动kibana就变成中文了
    在这里插入图片描述
  4. 启动kibana
    在这里插入图片描述
  5. 浏览器访问localhost:5601,kibana会自动去访问es的9200端口,出现以下界面,表示启动成功!
    在这里插入图片描述

四、ES核心概念

es是一个全文搜索引擎,那es是如何存储数据的呢?es的数据结构是什么,和传统的mysql、oracle一样吗?es如何实现搜索的功能呢?

首先要理解清楚一个概念,es是面向文档的,它里面不像数据库mysql一样有库、表、字段等概念,es中说的是索引、类型、文档、字段这几个概念,我们可以将传统的db和es做一个概念的对比如下:
在这里插入图片描述
elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多 个文档(行),每个文档中又包含多个字段(列)。
在这里插入图片描述

上图就是es图形化界面管理工具head项目下的索引查看页面,可以看到一个索引下可以有多个type类型(这个type默认是_doc)。

一个索引默认有5个分片(又称主分片)构成,每个分片会有一个副本(又称复制分片),在es集群中,主分片和复制分片会在不同的节点下,这样有利于一个节点挂掉后数据也不会丢失。一个分片就是一个lucene索引,一个包含倒排索引的目录。

总结:也就是说一个es索引是由多个lucene索引组成的,如无特指,说起索引指的就是es索引

倒排索引的结构使得es在不扫描全部文档的情况下,就能知道哪些文档包含哪些关键字。

倒排索引的概念:简单理解就是把所有文档中的每个词提取出来,然后创建一个不含重复词条的列表来记录这些词都出现在哪个文档了,在查询的时候我们只需要去看这个不重复的词条列表就可以快速的定位到与当前所查找的关键字相匹配的文档了。
在这里插入图片描述
如上图,若我们不用倒排索引,那需要检索所有的文档提取出与所查关键词相匹配的文档;而使用倒排索引我们直接就可以定位到所匹配的文档的id,这样更快!

五、IK分词器

分词:es是一个搜索引擎,那肯定是用来搜索的,es中默认的分词是把中文的每一个字看成一个词,这显然是不合理的,比如搜索一个“今天天气如何” , 那这句话里面的今天应该是一个词,天气又是一个词,不能把这句话每个字都分出来去查询吧,那样查询出来的结果不是我们想要的。所以我们需要安装中文分词器IK来解决这个分词的问题。

  1. 下载IK分词器: ik分词器下载地址,注意要下载和你es版本对应的ik分词器的版本,不对应的话es会启动不成功!
  2. 下载后解压,并将文件拷贝至ElasticSearch根目录下的 plugins 目录中。
    在这里插入图片描述
  3. 重新启动es

IK有两种分词的算法ik_smart 和 ik_max_word

ik_smart:粗粒度分词,优先匹配最长的词,就是把一句话中最长的词列出来即可,像下面的这句话“今天天气怎么样啊” ,因为“今天天气”是一个词,那它就不会在对这个词进行细分了,怎么样也不会再细分了
在这里插入图片描述
ik_max_word:细粒度分词,这个分词算法会穷尽一句话中所有分词的可能
在这里插入图片描述

自定义词库:有些中文词不在ik分词算法中,比如"伐木累",但是我们想让它在进行搜索分词时当成一个词,此时我们需要编写一个自定义词库。

  1. 进入ik的config目录下,新建一个文件hhl.dic,并在该文件中写入伐木累这个词
    在这里插入图片描述
  2. 修改当前目录下的IKAnalyzer.cfg.xml
    在这里插入图片描述
  3. 修改完毕重启es

然后在kibana中测试,可以发现伐木累已经被分成一个词了
在这里插入图片描述

六、ES基本操作

ES的操作时基于Resutful风格的请求,Restful是一种软件架构风格,不是标准,只是提供了一组设计规则和约束条件,使用restful可以让我们的请求更加规范更简洁更有层次,更易于实现缓存等机制。(restful是一种风格,我们的软件应该尽可能的都去使用restful这种风格)

ES中基本Rest命令说明:
在这里插入图片描述
上面已经把es的基本概念和数据结构了解的差不多了,下面进入es的一些基本增删改查的操作,这些操作我们先在kibana中dev_tools下的Console控制台中完成。

# 增加一条数据,索引为hhl,类型为user,id为1 ,文档内容就是下面的内容
PUT /hhl/user/1
{
   
  "name": "詹姆斯",
  "age": 23,
  "desc": "湖人"
}

# 查询数据
GET hhl/user/1
返回结果如下:
{
   
  "_index" : "hhl",
  "_type" : "user",
  "_id" : "1",
  "_version" : 8,
  "_seq_no" : 15,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
   
    "name" : "詹姆斯",
    "age" : 23,
    "desc" : "湖人"
  }
}

# 删除数据
DELETE hhl/user/1
# 更新数据,要修改的内容需放到doc文档中
POST hhl/user/1/_update
{
   
  "doc":{
   
    "name":"韦德",
    "age":3
  }
}


GET hhl/user/_search?q=name:杜兰

# 构建查询,这种才是开发中常用的写法,上面的一般不用(可以理解为上面的详细写法)
GET hhl/user/_search
{
   
  "query": {
   
    "match": {
   
      "name": "杜兰"
    }
  }
}

# 不加条件,查询所有
GET hhl/user/_search

# 等效于上面的查询所有
GET hhl/user/_search
{
   
  "query": {
   
    "match_all": {
   }
  }
}


# _source 指定查询哪些字段,类似数据库中的select a.name,a.age from a
GET hhl/user/_search
{
   
  "query": {
   
    "match": {
   
      "name": "杜兰"
    }
  },
  
  "_source": ["name","age"]
}


# sort 排序,根据age降序排列。注意:排序字段只能是数字、日期、id 这三种
GET hhl/user/_search
{
   
  "query": {
   
    "match_all": {
   }
  },
  "sort": [
    {
   
      "age": {
   
        "order": "desc"
      }
    }
  ]
}

# 分页查询 from:从第几条开始 size:查询几条数据
GET hhl/user/_search
{
   
  "query": {
   
    "match_all": {
   }
  },
  "from": 0,
  "size": 3
}


# 多条件查询,不是直接写两个match,而是要像下面这么写,bool 布尔查询 must就是and的意思
GET hhl/user/_search
{
   
  "query": {
   
    "bool": {
   
      "must": [
        {
   
         "match": {
   
           "name": "杜兰"
         } 
        },
        {
   
          "match": {
   
            "age": 35
          }
        }
      ]
    }
  }
}

# should 就是 or
GET hhl/user/_search
{
   
  "query": {
   
    "bool": {
   
      
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值