elasticsearch的学习(可供参考)

elasticsearch的学习

本文档的编写时根据腾讯云服务器centos7 和 es6.x版本进行编写
注意:es安装部分还没更新。。。。有问题可以留言。是根据6.x来的7.x的安装我会另外写一篇博文。。
因为第一次学习,教程中用的时es6,然后我自己都是用最新的,发现,最新的和视频教程中,很大区别,包括安装和处理报错信息,安装部分是我根据es7.x的截图,发现到后面错误解决不了,为了赶时间,学习,我又跟随视频中用es6.8来,所以这个文档,安装部分是es7.x的截图,理论知识并无太大区别。。这两天,在学习微信小程序,后面。再更新一下这个博文

一、什么是lucene?

Lucene是免费开源用于全文检索的程序工具包(API),由Apache软件基金会支持和提供。目前主流的java搜索框架都是依赖Lucene,官网:http://lucene.apache.org

我们为什么不直接使用它呢?Lucene底层的api调用起来非常复杂,代码的编写量会大大增加,因为es基于它封装和优化,使用起来就简单非常多。

二、搜索介绍

如果有了解过sphinx的就是一样的东西都是用来搜索数据,高亮数据等。

1、数据库搜索产生的问题

todo 画图

2、什么是全文检索?

全文检索是利用倒排索引技术对需要搜索的数据进行处理,然后提供快速匹配的技术。

其实全文检索还有另外一种专业定义,先创建索引然后对索引进行搜索的过程,就是全文检索。

(1)、倒排索引的理解?

倒排索引是一种存储数据的方式,与传统查找有很大区别
传统查找方式:采用数据按行存储,查找时逐行扫描,或者根据索引查找,然后匹配搜索条件,效率较差。概括来讲是先找到文档,然后看是否匹配。

倒排索引:首先对数据按列拆分存储,然后对文档中的数据分词,对词条进行索引,并记录词条在文档中出现的位置。这样查找时只要找到了词条,就找到了对应的文档。概括来讲是先找到词条,然后看看哪些文档包含这些词条

(2)、创建倒排索引的流程

(1)、创建文档列表
首先将数据按列进行拆分存储,类型于mysql的表存储,每一条数据,就是一个文档,形成文档列表
(2)、创建倒排索引列表
然后对文档中的数据进行分词,得到词条。对词条进行编号,并以词条创建索引。然后记录下包含该词条的所有文档编号(及其它信息)。

在这里插入图片描述

(3)、倒排索引的搜索过程

用图来理解
在这里插入图片描述

(4)、全文检索应用场景

1.当数据库搜索不能满足我们的业务需求的时候,比如海量数据搜索
2.需要进行相关度排序,高亮显示等操作

三、分词器

Analyzer(分词器)的作用是把一段文本中的词按规则取出所包含的所有词。对应的是Analyzer类,这是一个抽象类,切分词的具体规则是由子类实现的,所以对于不同的语言(规则),要用不同的分词器

注意:在创建索引时会用到分词器,在使用字符串搜索时也会用到分词器,这两个地方要使用同一个分词器,否则可能会搜索不出结果。所以当改变分词器的时候,需要重新建立索引库

1、常见的中文分词器

中文的分词比较复杂,因为不是一个字就是一个词,而且一个词在另外一个地方就可能不是一个词,如在“帽子和服装”中,“和服”就不是一个词。对于中文分词,通常有三种方式:单字分词、二分法分词、词典分词

(1)、单字分词

就是按照中文一个字一个字地进行分词,效率比较低。如:“我们是中国人”,效果:“我”、“们”、“是”、“中”、“国”、“人”。(StandardAnalyzer就是这样),es默认就是单字分词

(2)、二分法分词

按两个字进行切分,把相邻的两个字组成词分解出来,效率也比较低。而且很多情况下分的词不对。如:“我们是中国人”,效果:“我们”、“们是”、“是中”、“中国”、“国人”。(CJKAnalyzer就是这样)

(3)、词库分词(IKAnalyzer)

按某种算法构造词,然后去匹配已建好的词库集合,如果匹配到就切分出来成为词语。通常词库分词被认为是最理想的中文分词算法。如:“我们是中国人”,效果为:“我们”、“中国人”。(使用极易分词的MMAnalyzer。可以使用“极易分词”,或者是“庖丁分词”分词器、IKAnalyzer)。

四、什么是Elasticsearch

Elasticsearch官网

https://www.elastic.co/cn/products/elasticsearch

Elaticsearch简称为es,是一个开源的可扩展的全文检索引擎服务器,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。es使用Java开发并使用Lucene作为其核心来实现索引和搜索的功能,但是它通过简单的RestfulAPI和javaAPI来隐藏Lucene的复杂性,从而让全文搜索变得简单。

五、Elasticsearch的安装(需要修改)

环境准备:centos7 ,
注意:如果是es7.0以上是不需要安装jdk8了的。

我这里是安装的最新的es7.9,如果你是低版本则需要按照jdk8以及以上,最新版请忽略

jdk8(=jdk1.8)安装

#查找
yum search java|grep jdk

#下载
yum install java-1.8.0-openjdk.x86_64

在这里插入图片描述

(1)、新建用户

出于安全考虑,elasticsearch默认不允许以root账号运行

#增加用户
useradd elastic

#passwd+用户名 用这条命令激活并更改密码用户才可用
passwd elastic

因为学习阶段,我设置密码为root,你们可以自行设置,一般像腾讯云服务器默认密码都很复杂,因为重装镜像的时候设置太简单无法重装,设置太简单会有如下提示
在这里插入图片描述
切换用户

su - elastic

在这里插入图片描述

(2)下载软件,并上传,解压

https://www.elastic.co/cn/downloads/elasticsearch

在这里插入图片描述
上传压缩包到 usr/local/src/ ,我个人的习惯是所有的源码包统统在这个文件夹进行统一管理
在这里插入图片描述

解压
注意:这个步骤因为你此时是elatisc用户所有直接解压到 usr/local/src/是没有权限的,需要解压到自己的家目录

tar -zxvf elasticsearch-7.9.1-linux-x86_64.tar.gz -C /home/elastic/

#改一下啊目录的名称
mv /home/elastic/elasticsearch-7.9.1/  /home/elastic/elasticsearch

查看目录结构
在这里插入图片描述

名称解释
bin二进制脚本,包含启动命令等
config配置文件目录
jdk自带jdk
lib依赖包目录
logs日志文件目录
modules模块库
plugins插件目录(IK分词器插件)
data数据储存目录(暂时没有,需要在配置文件中指定存放位置,启动es时会自动根据指定位置创建)

此时的plugins是空的
在这里插入图片描述

(3)修改配置

修改jvm配置,注意如果太小的同样也启动不

-Xms512m
-Xmx512m

在这里插入图片描述

打开 elasticsearch.yml文件修改下面这几个配置。

data 和logs的目录

path.data: /home/elastic/elasticsearch/data
#
# Path to log files:
#
#path.logs: /path/to/logs
path.logs: /home/elastic/elasticsearch/logs

允许所有的域名访问

#network.host: 192.168.0.1
network.host: 0.0.0.0

(4)解决启动报错

切换到bin目录下,直接启动,会报错

./Elasticsearch

#启动方式二:后台启动
./elasticsearch -d

在这里插入图片描述
问题一:

max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]
elasticsearch用户拥有的最大虚拟内存太小,至少需要262144;

解决办法

注意这个配置文件 是在 /etc 下面 。不要去安装目录找

vim /etc/sysctl.conf 

G 跳转到文件末尾 添加

vm.max_map_count=262144

保存退出后,立即执行

sysctl -p

问题二:
the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodes] must be configured
默认发现设置不适合生产使用;至少有一个[discovery.seed\u主机, discovery.seed_提供程序, cluster.initial_master_节点]必须配置

解决办法:
切换到安装目录

vim config/elasticsearch.yml

将 #cluster.initial_master_nodes: [“node-1”, “node-2”] 修改为 cluster.initial_master_nodes: [“node-1”]

然后启动es,终于大功告成

在这里插入图片描述
直接访问 ip:9200
在这里插入图片描述
有的同学到达这一步,还是访问不了,会出现如下情况
在这里插入图片描述
如果此时 还是访问不了。需要关闭一下防火墙,如果是云服务器需要配置一下安装组规则

查看防火墙:
firewall-cmd --state   (centos7)

关闭防火墙:
systemctl stop firewalld.service   (centos7)

禁止开机启动防火墙:
systemctl disable firewalld.service  (centos7)

六、kibana

默认端口5601

它是elasticsearch的图形化界面工具,和下面类似
mysql HeidiSQL、Navcat、PhpMyadmin
redis RedisDesktopManager
memcached memadmin

1、下载,直接到下载页面

https://www.elastic.co/cn/downloads/kibana

2、上传

3、解压

4、修改配置

进入kibana目录修改配置文件

vim /config/kibana.yml
#server.host: "localhost"
server.host: "0.0.0.0"


#修改语言包 默认是en
i18n.locale: "zh-CN"

5、启动kibana

./bin/kibana

访问你的ip地址:5601

ctrl+i 自动缩进
ctrl+回车 执行语句
在这里插入图片描述

七、IK分词集成

Lucene的IK分词器早在2012年已经没有维护了,现在我们要使用的是在其基础上维护升级的版本,并且开发为Elasticsearch的集成插件了,与Elasticsearch一起维护升级,版本也保持一致,所以下载时一定要下载对应的版本

https://github.com/medcl/elasticsearch-analysis-ik

1、安装

方式一:使用插件安装
在elasticsearch的bin目录下执行以下命令,es插件管理器会自动帮我们安装,然后等待安装完成就行了

./elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.8.0/elasticsearch-analysis-ik-6.8.0.zip

下载完成后会提示 Continue with installation?输入 y 即可完成安装

方式二:上传安装包安装(推荐)

elasticsearch/plugins目录下创建analysis-ik目录

mkdir analysis-ik

复制到该目录然后解压

cp /usr/local/src/elasticsearch-analysis-ik-6.8.0.zip /home/elastic/elasticsearch/plugins/analysis-ik

重启es 和kibana即可成功集成IK分词

2、分词模式

IK分词器有两种分词模式:ik_max_wordik_smart模式。

(1)、ik_max_word (常用)

会将文本做最细粒度的拆分

ik_max_word 测试,前面分词器有讲到analyzer是一个抽象类。

POST  _analyze
{
  "analyzer": "ik_max_word",
  "text": "新华社长江前线"
}

输出结果
在这里插入图片描述

(2)、ik_smart

会做最粗粒度的拆分

ik_smart测试:

POST  _analyze
{
  "analyzer": "ik_smart",
  "text": "新华社长江前线"
}

执行结果

在这里插入图片描述

问题引申:如果江前线是一个人名我们该匹配出来呢?答:添加拓展词

3、添加扩展词典和停用词典

(1)、停用词

有些词在文本中出现的频率非常高,但对本文的语义产生不了多大的影响,比如的、呢、啊、了这些词。
停用词经常被过滤掉,不会被进行索引。
停用词可以加快索引的速度,减少索引库文件的大小。

(2)、扩展词

就是不想让哪些词被分开,让他们分成一个词。比如上面的江前线

(3)、自定义扩展词库操作

1.进入到 elasticsearch/config/analysis-ik/(插件安装方式) 或 elasticsearch/plugins/analysis-ik/config(安装包安装方式) 目录下, 新增自定义词典

vim myext_dict.dic

输入 :江前线
在这里插入图片描述

2.将我们自定义的扩展词典文件添加到IKAnalyzer.cfg.xml配置中

vim IKAnalyzer.cfg.xml

在这里插入图片描述

3.然后重启es和kibana后再次测试
在这里插入图片描述

八、API的学习

Elasticsearch提供了Rest风格的API,即http请求接口,而且也提供了各种语言的客户端API

1、Rest风格的API

文档地址

https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

在这里插入图片描述

2、客户端API

Elasticsearch支持的客户端非常多

https://www.elastic.co/guide/en/elasticsearch/client/index.html

在这里插入图片描述

九、ElasticSearch相关概念

Elasticsearch是基于Lucene的全文检索库,本质也是存储数据,很多概念与MySQL类似的。注意:es7.x版本中,已经移除了type概念

对比关系

索引库(indexes)---------------------------------Databases 数据库

类型(type)----------------------------------Table 数据表

文档(Document)--------------------------Row 行

字段(Field)---------------------Columns 列

映射配置(mappings)--------- 表结构

概念说明
索引库(indexes)索引库包含一堆相关业务,结构相似的文档document数据,比如说建立一个商品product索引库,里面可能就存放了所有的商品数据。
类型(type)type是索引库中的一个逻辑数据分类,一个type下的document,都有相同的field,类似于数据库中的表。比如商品type,里面存放了所有的商品document数据。6.0版本以后一个index只能有1个type,6.0版本以前每个index里可以是一个或多个type。
文档(document)文档是es中的存入索引库最小数据单元,一个document可以是一条客户数据,一条商品数据,一条订单数据,通常用JSON数据结构表示。document存在索引库下的type类型中。
字段(field)Field是Elasticsearch的最小单位。一个document里面有多个field,每个field就是一个数据字段
映射配置(mappings)类型对文档结构的约束叫做映射(mapping),用来定义document的每个字段的约束。如:字段的数据类型、是否分词、是否索引、是否存储等特性。类型是模拟mysql中的table概念。表是有结构的,也就是表中每个字段都有约束信息;

十、索引库的操作

1、创建索引库

语法

PUT /blog1
{
  "settings": {
    "属性名": "属性值"
  }
}

settings:就是索引库设置,其中可以定义索引库的各种属性,目前我们可以不设置,都走默认
在这里插入图片描述

1、查看索引库

语法:

GET /blog1

在这里插入图片描述

3、删除索引库

语法

DELETE /blog1

在这里插入图片描述
再次查看,返回索引不存在
在这里插入图片描述

十一、类型及映射操作

数据表和表结构的操作

有了索引库,等于有了数据库中的database。接下来就需要索引库中的类型了,也就是数据库中的表。创建数据库表需要设置字段约束,索引库也一样,在创建索引库的类型(等于创建表)时,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做字段映射(mapping)

字段的约束包括但不限于:

字段的数据类型
是否要存储
是否要索引
是否分词
分词器是什么

1.创建映射字段(需先创建索引库)

语法:

PUT /索引库名/_mapping/类型名称 或 索引库名/类型名称/_mapping
{
  "properties": {
    "字段名": {
      "type": "类型",
      "index": true,
      "store": true,
      "analyzer": "分词器"
    }
  }
}

类型名称:就是前面讲的type的概念,类似于数据库中的表
字段名:任意填写,下面指定许多属性,例如:

type:类型,可以是text、long、short、date、integer、object等
index:是否索引,默认为true  
store:是否存储,默认为false
analyzer:分词器,这里的ik_max_word即使用ik分词器

先创建一个空的索引库 shop
在这里插入图片描述
执行结果
在这里插入图片描述

2.映射属性详解

(1)type

Elasticsearch中支持的数据类型非常丰富
在这里插入图片描述

String类型,又分两种
text:可分词,不可参与聚合
keyword:不可分词,数据会作为完整字段进行匹配,可以参与聚合

Numerical:数值类型,分两类
基本数据类型:long、interger、short、byte、double、float、half_float
浮点数的高精度类型:scaled_float
(需要指定一个精度因子,比如10或100。elasticsearch会把真实值乘以这个因子后存储,取出时再还原。)

Date:日期类型
elasticsearch可以对日期格式化为字符串存储,但是建议我们存储为毫秒值,存储为long,节省空间。

Array:数组类型
进行匹配时,任意一个元素满足,都认为满足
排序时,如果升序则用数组中的最小值来排序,如果降序则用数组中的最大值来排序

Object:对象


{
    name:"Jack",
    age:21,
    girl:{
        name: "Rose", age:21
   }
}

如果存储到索引库的是对象类型,例如上面的girl,会把girl变成两个字段:girl.name和girl.age

(2)index

index影响字段的索引情况。

true:字段会被索引,则可以用来进行搜索。默认值就是true
false:字段不会被索引,不能用来搜索

index的默认值就是true,也就是说你不进行任何配置,所有字段都会被索引。
但是有些字段是我们不希望被索引的,比如商品的图片信息,就需要手动设置index为false。

(3)store

是否将数据进行独立存储。

原始的文本会存储在_source里面,默认情况下其他提取出来的字段都不是独立存储的,是从_source里面提取出来的。当然你也可以独立的存储某个字段,只要设置store:true即可,获取独立存储的字段要比从_source中解析快得多,但是也会占用更多的空间,所以要根据实际业务需求来设置,默认为false。

3.查看映射关系

语法

GET /索引库名/_mapping/类型名

示例:

GET /shop/_mapping/goods

执行结果

{
  "shop" : {
    "mappings" : {
      "goods" : {
        "properties" : {
          "images" : {
            "type" : "keyword",
            "index" : false
          },
          "price" : {
            "type" : "float"
          },
          "subtitle" : {
            "type" : "text",
            "analyzer" : "ik_max_word"
          },
          "title" : {
            "type" : "text",
            "analyzer" : "ik_max_word"
          }
        }
      }
    }
  }
}

4.一次创建索引库和类型(常用)

刚才 的案例中我们是把创建索引库和类型分开来做,其实也可以在创建索引库的同时,直接制定索引库中的类型
基本语法

put /索引库名
{
    "settings":{
        "索引库属性名":"索引库属性值"
    },
    "mappings":{
        "类型名":{
            "properties":{
                "字段名":{
                    "映射属性名":"映射属性值"
                }
            }
        }
    }
}

示例:

PUT /shop
{
  "settings": {},
  "mappings": {
    "goods": {
      "properties": {
        "title": {
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "subtitle": {
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "images": {
          "type": "keyword",
          "index": "false"
        },
        "price": {
          "type": "float"
        }
      }
    }
  }
}

执行结果

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "shop"
}

十二、文档操作(Row 行)

文档,即索引库中某个类型下的数据,会根据规则创建索引,将来用来搜索。可以类比做数据库中的每一行数据。

1、新增文档

(1)不指定ID,随机生成

语法:

POST /索引库名/类型名
{
    "key":"value"
}

示例:

POST /shop/goods/
{
    "title":"小米手机",
    "images":"http://image.leyou.com/12479122.jpg",
    "price":2699.00
}

在这里插入图片描述

(1)自己指定ID

语法:

POST /索引库名/类型/id值
{
    ...
}

示例:

POST /shop/goods/1
{
    "title":"小米手机",
    "images":"http://image.leyou.com/12479122.jpg",
    "price":2699.00
}

在这里插入图片描述

1、查看文档

语法:

GET /shop/goods/默认随机生成的id
GET /shop/goods/或者自己指定的id

在这里插入图片描述
在这里插入图片描述

2、修改文档

id对应文档存在,则修改
id对应文档不存在,则新增

把刚才新增的请求方式改为PUT,就是修改,不过修改必须指定id
比如我们新增一条id为3的数据,不存在,则应该是新增

PUT /shop/goods/3
{
    "title":"超米手机",
    "images":"http://image.leyou.com/12479122.jpg",
    "price":3899.00
}

在这里插入图片描述
我们修改数据后再次执行

在这里插入图片描述

3、删除文档

(1)根据ID删除

语法:

DELETE /索引库名/类型名/id值

示例:

DELETE /shop/goods/1

在这里插入图片描述

(2)根据查询条件删除(post)

语法:

POST  /索引库名/_delete_by_query
{
  "query": { 
    "match": {
      "字段名": "搜索关键字"
    }
  }
}

示例

POST /shop/_delete_by_query
{
    "query": {
        "match": {
            "title": "小米"
        }
    }
}

在这里插入图片描述

(3)删除所有数据

语法:

POST  /索引库名/_delete_by_query
{
  "query": { 
    "match_all": {}
  }
}

示例:

POST  /shop/_delete_by_query
{
  "query": { 
    "match_all": {}
  }
}

在这里插入图片描述

十三、查询操作(重点)

准备学习测试数据,_bulk批量操作接口

POST /shop/goods/_bulk
{"index":{}}
{"title":"大米手机","images":"http://image.leyou.com/12479122.jpg","price":3288}
{"index":{}}
{"title":"小米手机","images":"http://image.leyou.com/12479122.jpg","price":2699}
{"index":{}}
{"title":"小米电视4A","images":"http://image.leyou.com/12479122.jpg","price":4288}

1、基本查询

语法:

POST /索引库名/_search
{
    "query":{
        "查询类型":{
            "查询条件":"查询条件值"
        }
    }
}

这里的query代表一个查询对象,里面可以有不同的查询属性
查询类型
例如:match_all, match,term , range 等等
查询条件:查询条件会根据类型的不同,写法也有差异,后面详细讲解

(1)、查询所有(match_all)

示例:

POST /shop/_search
{
  "query": {
    "match_all": {}
  }
}

执行结果

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 3,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "shop",
        "_type" : "goods",
        "_id" : "FVhZn3QBDwlWNzf7FI0_",
        "_score" : 1.0,
        "_source" : {
          "title" : "小米手机",
          "images" : "http://image.leyou.com/12479122.jpg",
          "price" : 2699
        }
      },
      {
        "_index" : "shop",
        "_type" : "goods",
        "_id" : "FlhZn3QBDwlWNzf7FI0_",
        "_score" : 1.0,
        "_source" : {
          "title" : "小米电视4A",
          "images" : "http://image.leyou.com/12479122.jpg",
          "price" : 4288
        }
      },
      {
        "_index" : "shop",
        "_type" : "goods",
        "_id" : "FFhZn3QBDwlWNzf7FI0_",
        "_score" : 1.0,
        "_source" : {
          "title" : "大米手机",
          "images" : "http://image.leyou.com/12479122.jpg",
          "price" : 3288
        }
      }
    ]
  }
}

解释说明

took:查询花费时间,单位是毫秒
time_out:是否超时
_shards:分片信息
hits:搜索结果总览对象
	total:搜索到的总条数
	max_score:所有结果中文档得分的最高分
	hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
		_index:索引库
		_type:文档类型
		_id:文档id
		_score:文档得分
		_source:文档的源数据

(2)、匹配查询(match)

会把查询条件进行分词,然后根据词条关系进行查询
词条关系有
1.or关系(默认)

POST /shop/_search
{
  "query": {"match": {
    "title": "小米电视"
  }}
}

不仅会查询到电视,而且与小米相关的都会查询到,多个词之间是or的关系
在这里插入图片描述

2.and关系
某些情况下,我们需要更精确查找,我们希望这个关系变成and,可以这样做:

POST /shop/_search
{"query": {"match": {
  "title": {"query": "小米电视4A","operator": "and"}
}}}

在这里插入图片描述

3.match和match_all查询结果中的max_score为什么不一样?
具体说明一下 max_score 是怎么回事?
因为创建索引库的时候我们指定了分词ik_max_word在进行查询的操作的时候会先分词,那么也就是说查询的结果越接近分出来的词得分越高,比如
你搜索 小米电视 那么 小米手机 小米电视4A 这两条数据 则是小米手机的更高,原因是因为没有小米电视这个词 因为小米电视被拆分成小米和电视

match_all 则是 查询所有,所以分值都一样都是 1

(3)、多字段查询(multi_match)

multi_match与match类似,不同的是它可以在多个字段中查询
为了测试效果我们在这里新增一条数据:

POST /shop/goods
{
    "title": "华为手机",
    "images": "http://image.leyou.com/12479122.jpg",
    "price": 5288,
    "subtitle": "小米"
}

示例:

POST /shop/_search
{
  "query": {
    "multi_match": {
      "query": "小米",
      "fields": ["title","subtitle"]
    }
  }
}

执行结果:
只要所查询的字段中包含小米的商品都会被查询出来
在这里插入图片描述

(4)、 词条匹配(term)

term 查询被用于精确值 匹配,这些精确值可能是数字、时间、布尔或者那些未分词的字符串

示例
查询出价格是2699的商品

POST /shop/_search
{
    "query":{
        "term":{
            "price":2699
        }
    }
}#或者这种写法都可以
POST /shop/_search
{
  "query": {
    "term": {
      "price": {
        "value": "2699"
      }
    }
  }
}

执行结果
在这里插入图片描述

(5)、 多词条精准匹配(terms)

terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,类似于mysql的in
示例
查询价格是2699和5288的

POST /shop/_search
{
    "query":{
        "terms":{
            "price":[2699,5288]
        }
    }
}

执行结果
在这里插入图片描述

2、结果过滤

默认情况下,elasticsearch在搜索的结果中,会把文档中保存在_source的所有字段都返回。

如果我们只想获取其中的部分字段,我们可以添加_source的过滤

(1)、直接指定字段

示例:
只获取title和price字段

POST /heima/_search
{
  "_source": ["title","price"],
  "query": {
    "term": {
      "price": 2699
    }
  }
}

执行结果
在这里插入图片描述

(2)、指定includes和excludes

includes:来指定想要显示的字段
excludes:来指定不想要显示的字段

示例:

POST /shop/_search
{
  "_source": {
    "includes":["title","price"]
  },
  "query": {
    "term": {
      "price": 2699
    }
  }
}
POST /shop/_search
{
  "_source": {
     "excludes": ["images"]
  },
  "query": {
    "term": {
      "price": 2699
    }
  }
}

两个结果都是一样的
在这里插入图片描述

3、高级查询

(1)、布尔组合(bool)

bool把各种其它查询通过must(与)、must_not(非)、should(或)的方式进行组合
示例代码

GET /shop/_search
{
    "query":{
        "bool":{
            "must":     { "match": { "title": "小米" }},
            "must_not": { "match": { "title":  "电视" }},
            "should":   { "match": { "title": "手机" }}
        }
    }
}

翻译一下:必须存在小米,一定不要电视,可以携带手机
执行结果
在这里插入图片描述

(2)、范围查询(range)

range 查询找出那些落在指定区间内的数字或者时间

操作符说明
gt大于
gte大于等于
lt小于
lte小于等于

示例

POST /shop/_search
{
    "query":{
        "range": {
            "price": {
                "gte":  3000,
                "lt":   5000
            }
        }
    }
}

在这里插入图片描述

(2)、模糊查询(fuzzy)

我们新增一个商品

POST /shop/goods/4
{
    "title":"apple手机",
    "images":"http://image.leyou.com/12479122.jpg",
    "price":5899.00
}

它允许用户搜索词条与实际词条出现偏差,但是偏差的编辑距离不得超过2

POST /shop/_search
{
  "query": {
    "fuzzy": {
      "title": "appla"
    }
  }
}

上面的查询,也能查询到apple手机
在这里插入图片描述

fuzziness,你的搜索文本最多可以纠正几个字母去跟你的数据进行匹配,默认如果不设置,就是2
注意:下面这个apeee也是可以匹配到的,因为ape是三个能匹配到的,最大只能错两个,所以剩余两个ee在容错范围内,如果是apeeee则匹配不到结果

POST /shop/_search
{
  "query": {
    "fuzzy": {
      "title": {
        "value": "apeee",
        "fuzziness": 2
      }
    }
  }
}

4、排序

sort可以让我们按照不同的字段进行排序,并且通过order指定排序的方式

(1)、单字段排序

示例代码

POST /shop/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "asc"
      }
    }
  ]
}

在这里插入图片描述

(2)、 多字段排序

和msyql一样可以设置多个排序字段
假定我们想要结合使用 price和 _score(得分) 进行查询,并且匹配的结果首先按照价格排序,然后按照相关性得分排序

POST /shop/_search
{
    "query":{
        "match": {
          "title": "小米"
        }
    },
    "sort": [
      { "price": { "order": "desc" }},
      { "_score": { "order": "desc" }}
    ]
}

在这里插入图片描述

5、高亮

和sphinx高亮原理是一样的,在使用match查询的同时,加上一个highlight属性

POST /shop/_search
{
  "query": {
    "match": {
      "title": "电视"
    }
  },
  "highlight": {
    "pre_tags": "<font color='pink'>",
    "post_tags": "</font>",
    "fields": {
      "title": {}
    }
  }
}

解释说明

pre_tags:前置标签
post_tags:后置标签
fields:需要高亮的字段
	title:这里声明title字段需要高亮,后面可以为这个字段设置特有配置,也可以空

在这里插入图片描述

6、分页

elasticsearch中实现分页的语法非常简单,一般是和排序在一起使用

POST /shop/_search
{
  "query": {
    "match_all": {}
  },
  "size": 2,
  "from": 0
}
size:每页显示多少条 

from:当前页起始索引,  int start = (pageNum - 1) * size;

十四、Elasticsearch集群

1、单点的问题

单台服务器,往往都有最大的负载能力,超过这个阈值,服务器性能就会大大降低甚至不可用。单点的elasticsearch也是一样,那单点的es服务器存在哪些可能出现的问题呢?

单台机器存储容量有限
单服务器容易出现单点故障,无法实现高可用
单服务的并发处理能力有限

所以,为了应对这些问题,我们需要对elasticsearch搭建集群
在这里插入图片描述

2、数据分片

首先,我们面临的第一个问题就是数据量太大,单点存储量有限的问题。

大家觉得应该如何解决?

没错,我们可以把数据拆分成多份,每一份存储到不同机器节点(node),从而实现减少每个节点数据量

在这里插入图片描述

3、数据备份

数据分片解决了海量数据存储的问题,但是如果出现单点故障,那么分片数据就不再完整,这又该如何解决呢?

没错,就像大家为了备份手机数据,会额外存储一份到移动硬盘一样。我们可以给每个分片数据进行备份,存储到其它节点,防止数据丢失,这就是数据备份,也叫数据副本(replica)。

数据备份可以保证高可用,但是每个分片备份一份,所需要的节点数量就会翻一倍,成本实在是太高了!

为了在高可用和成本间寻求平衡,我们可以这样做:

首先对数据分片,存储到不同节点
然后对每个分片进行备份,放到对方节点,完成互相备份
这样可以大大减少所需要的服务节点数量,如图,我们以3分片,每个分片备份一份为例:
在这里插入图片描述
在这个集群中,如果出现单节点故障,并不会导致数据缺失,所以保证了集群的高可用,同时也减少了节点中数据存储量。并且因为是多个节点存储数据,因此用户请求也会分发到不同服务器,并发能力也得到了一定的提升。

4、搭建集群

集群需要多台机器,我们这里用一台机器来模拟,因此我们需要在一台虚拟机中部署多个elasticsearch节点,每个elasticsearch的端口都必须不一样

node-01:http端口9201,TCP端口9301
node-02:http端口9202,TCP端口9302
node-03:http端口9203,TCP端口9303

接下来的所有操作,记得要使用elastic用户来操作,
注意这里是在一台服务器中模拟伪集群

(1)目录改名

把原来的elasticsearch目录改名为elasticsearch-01

mv elasticsearch/ elasticsearch-01/

(2)删除原有生成的测试数据

rm -rf elasticsearch-01/data/nodes/

(3)修改一下配置

vim config/elasticsearch.yml
#集群名称
cluster.name: es-stu

#节点名称
node.name: node-1

#数据和日志的目录
path.data: /home/elastic/elasticsearch-01/data
path.logs: /home/elastic/elasticsearch-01/logs

#默认的端口9200注释打开 改成9201
http.port: 9201

#这个配置文件是没有的,自己添加上去
transport.tcp.port: 9301

#集群中其它节点的ip及端口
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9301", "127.0.0.1:9302","127.0.0.1:9303"]

#注释打开,配置2,意思是假如总共3台挂了一台只剩下2台的时候也提供服务
discovery.zen.minimum_master_nodes: 2

在这里插入图片描述

(4)复制剩余两台es服务器

直接把elasticsearch-01复制成elasticsearch-02 elasticsearch-03即可

cp -r elasticsearch-01/ elasticsearch-02/
cp -r elasticsearch-01/ elasticsearch-03/

3台就已经准备完毕
在这里插入图片描述

(5)修改剩余两台es服务器的配置

第三台道理相同
在这里插入图片描述

在这里插入图片描述

(6)修改kibana的配置

默认是连接的9200,现在已经端口被我改成了9201 9202 92013,所以需要改一下

#打开注释,可以是数组,连接一台就可以了
elasticsearch.hosts: ["http://localhost:9201"]

(7)分别启动三个节点

我复制了三个会话
在这里插入图片描述

(8)通过head插件连接查看集群

在这里插入图片描述
在这里插入图片描述

(9)测试集群中创建索引库

如何测试es服务集群是一个高可用的?

在这里插入图片描述

PUT /shop
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  }
}

number_of_shards:分片数量,这里设置为3
number_of_replicas:副本数量,这里设置为1,每个分片一个备份,一个原始数据,共2份。

head查看,我们可以查看到分片的存储结构
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

此时,我们把节点3的那台服务器给停掉,则节点一的0分片会自动变成主分片
在这里插入图片描述

(10)通过kibana查看集群

先启动kibana
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
启动kibana后刷新head插件发现多了很多个,就是上面文档有那么多的原因
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十五、完结

基本的东西将完了,至于各个客户端操作大家自己根据文档,进行学习。我是学习php的,有的可能是java python 等等

如果是php的同学请移步我的另外一篇博客

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值