zoukankan      html  css  js  c++  java
  • ElasticSearch 7.8.1 从入门到精通

    学前导读

    1. ElasticSearch对电脑配置要求较高内存至少4G以上,空闲2G内存,线程数4018+
    2. 学习的时候,推荐将ElasticSearch安装到Linux或者mac上,极度不推荐装Windows上(坑太多,服务器部署的时候,也不会部署到Window上,学习用Windows上玩,不是耽误自个时间麽)。如果是Window用户想学这个,电脑自身至少16G,然后装虚拟机,在虚拟机上搞个Linux玩
    3. Linux系统不建议装6/6.5版本的(启动的时候,会检查内核是否3.5+,当然可以忽略这个检查),推荐装7+
    4. 自身电脑配置不高的话,怎么办呢?土豪做法,去买个云服务器叭,在云服务器上玩

    注意事项

      上面第1、2点未满足,又舍不得去买云服务器的小伙伴,就不要往下面看了,看了也白看,ElasticSearch对电脑配置要求较高,前置条件未满足的话,服务是起不来的。

    演示环境说明

      我演示的时候,是用的mac系统,上面装了个虚拟机,虚拟机版本Centos6.5,jdk用的13,ElasticSearch用的版本是 7.8.1。这些我使用的包我下面也会提供,为了学习的话,尽量和我使用的版本一致,这样大家碰到的问题都一样,安装过程中,我也猜了不少坑,都总结出来了,仔细阅读文档就可以捣鼓出来。

    什么是搜索引擎?

      常用的搜索网站:百度、谷歌

    数据的分类

    结构化数据

      指具有固定格式或有限长度的数据,如数据库,元数据等。对于结构化数据,我们一般都是可以通过关系型数据库(mysql、oracle)的table的方法存储和搜索,也可以建立索引。通过b-tree等数据结构快速搜索数据

    非结构化数据

      全文数据,指不定长或无固定格式的数据,如邮件,word等。对于非结构化数据,也即对全文数据的搜索主要有两种方式:顺序扫描法,全文搜索法

    顺序扫描法

      我们可以了解它的大概搜索方式,就是按照顺序扫描的方式查找特定的关键字。比如让你在一篇篮球新闻中,找出“科比”这个名字在那些段落出现过。那你肯定需要从头到尾把文章阅读一遍,然后标出关键字在哪些地方出现过

      这种方式毋庸置疑是最低效的,如果文章很长,有几万字,等你阅读完这篇新闻找到“科比”这个关键字,那得花多少时间

    全文搜索

      对非结构化数据进行顺序扫描很慢,我们是否可以进行优化?把非结构化数据想办法弄得有一定结构不就好了嘛?将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对这些有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这种方式就构成了全文搜索的基本思路。这部分从非结构化数据提取出的然后重新组织的信息,就是索引。

    什么是全文搜索引擎

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

    常见的搜索引擎

    Lucene

    • Lucene是一个Java全文搜索引擎,完全用Java编写。lucene不是一个完整的应用程序,而是一个代码库和API,可以很容易地用于向应用程序添加搜索功能
    • 通过简单的API提供强大的功能
      • 可扩展的高性能索引
      • 强大,准确,高效的搜索算法
      • 跨平台解决方案
    • Apache软件基金会
      • 在Apache软件基金会提供的开源软件项目的Apache社区的支持
      • 但是Lucene只是一个框架,要充分利用它的功能,需要使用Java,并且在程序中集成Lucene。需要很多的学习了解,才能明白它是如何运行的,熟练运用Lucene确实非常复杂

    Solr

    • Solr是一个基于Lucene的Java库构建的开源搜索平台。它以友好的方式提供Apache Lucene的搜索功能。它是一个成熟的产品,拥有强大而广泛的用户社区。它能提供分布式索引,复制,负载均衡以及自动故障转移和恢复。如果它被正确部署然后管理的好,他就能够成为一个高可用,可扩展且容错的搜索引擎
    • 强大功能
      • 全文搜索
      • 突出
      • 分面搜索
      • 实时索引
      • 动态集群
      • 数据库集成
      • NoSQL功能和丰富的文档处理

    ElasticSearch

    • ElasticSearch是一个开源,是一个机遇Apache Lucene库构建的Restful搜索引擎
    • ElasticSearch是Solr之后几年推出的。它提供了一个分布式,多租户能力的全文搜索引擎,具有HTTP Web页面和无架构JSON文档。ElasticSearch的官方客户端提供Java、Php、Ruby、Perl、Python、.Net和JavaScript
    • 主要功能
      • 分布式搜索
      • 数据分析
      • 分组和聚合
    • 应用场景
      • 维基百科
      • Stack Overflow
      • GitHub
      • 电商网站
      • 日志数据分析
      • 商品价格监控网站
      • BI系统
      • 站内搜索
      • 篮球论坛

    搜索引擎的快速搭建

    环境准备

      注意,我使用的linux搭建的,当然Window(极度不推荐,坑太多)也能搭建,ElasticSearch安装前需要先安装jdk,这里我使用的是jdk13,因为linux自带jdk版本,需要先将之前的jdk版本卸载(点我直达),在安装指定的jdk版本!!!

      开发环境,建议关闭防火墙,避免不必要的麻烦!!!!生产环境,视情况开启端口号!!!!

    service iptables stop   命令关闭防火墙,但是系统重启后会开启
    
    chkconfig iptables off--关闭防火墙开机自启动

    「注意事项」

      ElasticSearch强依赖jdk环境的,所以一定要安装对应的jdk版本并配置好相关的环境变量,比如ES7.X版本要装jdk8以上的版本,而且是要官方来源的jdk。启动的时候有可能会提示要装jdk11,因为ES7以上官方都是建议使用jdk11,但是一般只是提示信息,不影响启动。

    ES官网推荐JDK版本兼容地址:点我直达

      ES强依赖JVM,也很吃内存,所以一定要保证你的机器至少空闲出2G以上内存。推荐使用Linux,可以本地搭建虚拟机。

      启动一定要使用非root账户!!!!这是ES强制规定的。ElasticSearch为了安全考虑,不让使用root启动,解决办法是新建一个用户,用此用户进行相关的操作。如果你用root启动,会报错。如果是使用root账户安装ES,首先给安装包授权,比如chown -R 777 安装包路径。然后再使用非root账户启动,具体的权限配置,根据自己想要的配置。

    补充

      高版本ElasticSearch自带jdk版本的,Linux中我安装的是jdk13,没用ElasticSearch自带的jdk,有兴趣的小伙伴可以去研究下。

    下载

    官网地址:点我直达

    我使用的包(推荐和我版本保持一致)

    链接: https://pan.baidu.com/s/1jjNEErHtBu93HmvxKCT5Sw  密码: kbcs

    修改配置文件

    1、修改elasticsearch-x.x.x/config/elasticsearch.yml,主要修改成以下内容

    cluster.name: my-application
    node.name: node-1
    network.host: 0.0.0.0
    http.port: 9200
    discovery.seed_hosts: ["127.0.0.1", "[::1]"]
    cluster.initial_master_nodes: ["node-1"]
    
    bootstrap.system_call_filter: false
    http.cors.allow-origin: "*"
    http.cors.enabled: true
    http.cors.allow-headers : X-Requested-With,X-Auth-Token,Content-Type,Content-Length,Authorization
    http.cors.allow-credentials: true

    2、来到elasticsearch-x.x.x/bin下,执行:sh elasticsearch启动,报错,修改配置文件elasticsearch-env

    3、设置用户和组 

    groupadd elsearch
    #添加用户组,语法:groupadd 组名
    useradd elsearch -g elsearch -p elasticsearch
    #添加用户,并将用户添加到组中,语法:useradd 用户名 -p 密码 -g 组名
    chown -R elsearch:elsearch  elasticsearch-6.3.0
    # 给用户组授权,语法:chown -R 用户:组名 es安装完整路径

    注意=================以上root用户操作=============== 

    注意=================以下es用户操作================

    注意:若es用户密码登录不上,在回到root用户下,修改es用户的密码,语法:passwd 要修改用户名

    4、登录到es用户下,继续启动ElasticSearch,执行:sh elasticsearch

    报错如下:
    java.lang.UnsupportedOperationException: seccomp unavailable: requires kernel 3.5+ with CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER compiled in
    
    原因:我用的Centos6.5,其linux内核版本为2.6。而Elasticsearch的插件要求至少3.5以上版本。
    
    
    解决方案:禁用这个插件即可
    修改elasticsearch.yml文件,在最下面添加如下配置:
    bootstrap.system_call_filter: false

    5.继续启动ElasticSearch,执行:sh elasticsearch

    修改一下内容需要使用root权限

    报错如下4条:
    [1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
    [2]: max number of threads [1024] for user [es] is too low, increase to at least [4096]
    [3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
    [4]: 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
    
    ==========分割线===============
    解决办法如下
    1、vim /etc/security/limits.conf文件,添加
    * soft nofile 65535
    * hard nofile 65535
    
    2、vim /etc/security/limits.conf文件,添加
    * soft nproc  4096
    * hard nproc  4096
    
    3、vim /etc/sysctl.conf 文件,添加
    vm.max_map_count=262144  
    
    4、vim /var/soft/es7.8.1/elasticsearch-7.8.1/config/elasticsearch.yml 文件,添加
    cluster.initial_master_nodes: ["node-1"]

    修改完之后,一定要重启,重启,重启,重要的事儿说三遍!!!!!

    上面第2条问题,线程数修改不了,可以尝试使用这个方法修改线程数

    Elasticsearch7.8.1 [1]: max number of threads [1024] for user [es] is too low, increase to at least [4096]异常
    
    根据linux系统差异,有时候需要来点终极解决方案
    
    新建: /etc/security/limits.d/test-limits.conf
    
    cat>>test-limits.conf
    
    
    
    然后加下内容:
    
    * soft nofile 65535
    
    * hard nofile 65535
    
    * soft nproc 4096
    
    * hard nproc 4096
    
    
    ctrl+d保存即可;
    
    
    然后重启服务器即可;

    配置小结

      1、第一次配置过程中,踩了不少坑,我踩过的坑,都在上面记录了

      2、如果照我上面哪个方法还解决不了,自行根据ElasticSearch日志,百度去找答案叭····

    启动

    正常启动

    进入软件的安装目录,进入到bin
    执行:sh elasticsearch

    守护进行启动

    进入软件的安装目录,进入到bin
    执行:sh elasticsearch -d -p pid

    验证

      打开浏览器输入:127.0.0.1:9200

    ElasticSearch目录结构介绍

    类型 描述 默认位置 设置
    bin
    ⼆进制脚本包含启动节点的elasticsearch
    {path.home}/bin
     
    conf
    配置⽂件包含elasticsearch.yml 
    {path.home}/confifig
    path.conf
    data
    在节点上申请的每个index/shard的数据⽂件的位置。
    可容纳多个位置
    {path.home}/data
    path.data
    logs
    ⽇志⽂件位置
    {path.home}/logs
    path.logs
    plugins
    插件⽂件位置。每个插件将包含在⼀个⼦⽬录中。
    {path.home}/plugins
    path.plugins

    ElasticSearch快速入门

    核心概念

    前言

      传统数据库查询数据的操作步骤是这样的:建立数据库->建表->插入数据->查询

    索引(index)

      一个索引可以理解成一个关系型数据库

    类型(type)

      一个type就像一类表,比如user表、order表

      注意

        1、ES 5.X中一个index可以有多种type

        2、ES 6.X中一个index只能有一种type

        3、ES 7.X以后已经移除type这个概念

    映射(mapping)

      mapping定义了每个字段的类型等信息。相当于关系型数据库中的表结构

    文档(document)

      一个document相当于关系型数据库中的一行记录

    字段(field)

      相当于关系型数据库表的字段

    集群(cluster)

      集群由一个或多个节点组成,一个集群由一个默认名称“elasticsearch”

    节点(node)

      集群的节点,一台机器或者一个进程

    分片和副本(shard)

    • 副本是分片的副本。分片有主分片(primary Shard)和副本分片(replica Shard)之分
    • 一个Index数据在屋里上被分布在多个主分片中,每个主分片只存放部分数据
    • 每个主分片可以有多个副本,叫副本分片,是主分片的复制

    RESTful风格的介绍

    介绍

    •  RESTful是一种架构的规范与约束、原则,符合这种规范的架构就是RESTful架构
    • 先看REST是什么意思,英文Representational state transfer表述性状态转移,其实就是对资源的标书性状态转移,即通过HTTP动词来实现资源的状态扭转
    • 资源是REST系统的核心概念。所有的设计都是以资源为中心
    • elasticsearch使用RESTful风格api来设计的

    方法

    action 描述
    HEAD 只获取某个资源的头部信息
    GET 获取资源
    POST 创建或更新资源
    PUT 创建或更新资源
    DELETE 删除资源
    GET /user:列出所有的⽤户
    POST /user:新建⼀个⽤户
    PUT /user:更新某个指定⽤户的信息
    DELETE /user/ID:删除指定⽤户

    调试工具

    Postman工具(推荐)

    curl工具

    获取elasticcsearch状态

    curl -X GET "http://localhost:9200"

    新建一个文档

    curl -X PUT "localhost:9200/xdclass/_doc/1" -H 'Content-Type:
    application/json' -d' {
    "user" : "louis",
    "message" : "louis is good"
    }

    删除一个文档

    curl -X DELETE "localhost:9200/xdclass/_doc/1"

    索引的使用

    新增

    单个获取

    批量获取

    删除

    获取所有

    方式一

    方式二

    判断索引是否存在(存在,返回200,不存在404)

    关闭索引

      此时再次查询cba时,返回json会多一行

    打开索引

      关闭索引标记消失

    映射的使用

    介绍

      定义索引的结构,之前定义一个nba索引,但是没有定义他的结构,我们现在开始建立mapping;

      type="keyword":是一个关键字,不会被分词

      type="text":会被分词,使用的是全文索引

    新增

    json格式

    {
        "properties": {
            "name": {
                "type": "text"
            },
            "team_name": {
                "type": "text"
            },
            "position": {
                "type": "keyword"
            },
            "play_year": {
                "type": "keyword"
            },
            "jerse_no": {
                "type": "keyword"
            }
        }
    }

    获取

    批量获取

    获取所有mapping

    方式一

    方式二

    添加一次字段

    文档的操作

    新增

    不指定索引方式新增

    踩坑(要POST请求)

    PUT请求改POST

    自动创建索引

    • 查看auto_create_index开关状态,请求:http://ip:port/_cluster/settings

    • 当索引不存在并且auto_create_index为true的时候,新增文档时会自动创建索引
    • 修改auto_create_index状态
      • put方式:ip:port/_cluster/settings

    {
    "persistent": {
        "action.auto_create_index": "false"
     }
    }

      当auto_create_index=false时,指定一个不存在的索引,新增文档

    {
        "name":"杨超越",
        "team_name":"梦之队",
        "position":"组织后卫",
        "play_year":"0",
        "jerse_no":"18"
    }

    指定操作类型

    PUT请求:ip:port/xxx/_doc/1?op_type=create

    文档查看

    查看多个文档

    方式一

    {
        "docs": [{
                "_index": "nba",
                "_type": "_doc",
                "_id": "1"
            },
            {
                "_index": "nba",
                "_type": "_doc",
                "_id": "2"
            }
        ]
    }

    方式二

    方式三

    方式四

    修改

    向_source字段,增加一个字段

    {
        "script": "ctx._source.age = 18"
    }

    从source字段,删除一个字段

    {
        "script": "ctx._source.remove("age")"
    }

    根据参数值,更新指定文档的字段

      upsert当指定的文档不存在时,upsert参数包含的内容将会被插入到索引中,作为一个新文档;如果指定的文档存在,ElasticSearch引擎将会执行指定的更新逻辑。

    删除文档

    搜索的简单使用

    准备工作

    删除nba索引

    新建一个索引

    并指定mapping

    {
        "mappings": {
            "properties": {
                "name": {
                    "type": "text"
                },
                "team_name": {
                    "type": "text"
                },
                "position": {
                    "type": "text"
                },
                "play_year": {
                    "type": "long"
                },
                "jerse_no": {
                    "type": "keyword"
                }
            }
        }
    }

    新增document

    192.168.199.170:9200/nba/_doc/1
    {
        "name": "哈登",
        "team_name": "⽕箭",
        "position": "得分后卫",
        "play_year": 10,
        "jerse_no": "13"
    }
    192.168.199.170:9200/nba/_doc/2
    {
        "name": "库⾥",
        "team_name": "勇⼠",
        "position": "控球后卫",
        "play_year": 10,
        "jerse_no": "30"
    }
    192.168.199.170:9200/nba/_doc/3
    {
        "name": "詹姆斯",
        "team_name": "湖⼈",
        "position": "⼩前锋",
        "play_year": 15,
        "jerse_no": "23"
    }

    词条查询(term)

      词条查询不会分析查询条件,只有当词条和查询字符串完全匹配时,才匹配搜索。

    单挑term查询

    {
        "query": {
            "term": {
                "jerse_no": "23"
            }
        }
    }

    多条term查询

    {
        "query": {
            "terms": {
                "jerse_no": [
                    "23",
                    "13"
                ]
            }
        }
    }

    全文查询(full text)

      ElasticSearch引擎会先分析查询字符串,将其拆分成多个分词,只要已分析的字段中包含词条的任意一个,或全部包含,就匹配查询条件,返回该文档;如果不包含任意一个分词,表示没有任何问的那个匹配查询条件

    match_all

    {
        "query": {
            "match_all": {}
        },
        "from": 0,
        "size": 10
    }

    match

    {
        "query": {
            "match": {
                "position":"后卫"
            }
        },
        "from": 0,
        "size": 10
    }

    multi_match

    {
        "query": {
            "multi_match": {
                "query": "shooter",
                "fields": ["title", "name"]
            }
        }
    }
    post 192.168.199.170:9200/nba/_update/2
    {
        "doc": {
            "name": "库⾥",
            "team_name": "勇⼠",
            "position": "控球后卫",
            "play_year": 10,
            "jerse_no": "30",
            "title": "the best shooter"
        }
    }

    match_phrase

      类似于词条查询,精准查询

    match_phrase_prefix

      前缀匹配

    {
        "query": {
            "match_phrase_prefix": {
                "title": "the best s"
            }
        }
    }
    post 192.168.199.170:9200/nba/_update/3
    {
        "doc": {
            "name": "詹姆斯",
            "team_name": "湖⼈",
            "position": "⼩前锋",
            "play_year": 15,
            "jerse_no": "23",
            "title": "the best small forward"
        }
    }

    分词器的介绍和使用

    什么是分词器

    • 将用户输入的一段文本,按照一定逻辑,分析成多个词语的一种工具
    • example:The best 3-points shooter is Curry!

    常用的内置分词器

    1. standard analyzer
    2. simple analyzer
    3. whitespace analyzer
    4. stop analyzer
    5. language analyzer
    6. pattern analyzer

    standard analyzer

      标准分析器是默认分词器,如果未指定,则使用该分词器

    {
        "analyzer": "standard",
        "text": "The best 3-points shooter is Curry!"
    }

    simple analyzer

      simple分析器当他遇到只要不是字母的字符,就将文本解析成term,而且所有的term都是小写

    whitespace analyzer

      whitespace分析器,当他遇到空白字符时,就将文本解析成terms

    stop analyzer

      stop分析器和simple分析器很想,唯一不同的是,stop分析器增加了对删除停止词的支持,默认使用了english停止词

      stopwords预定义的停止词列表,比如(ths,a,an,this,of,at)等等

    language analyzer

    (特定的语⾔的分词器,⽐如说,english,英语分词器),内置语⾔:arabic, armenian,
    basque, bengali, brazilian, bulgarian, catalan, cjk, czech, danish, dutch, english, fifinnish,
    french, galician, german, greek, hindi, hungarian, indonesian, irish, italian, latvian,
    lithuanian, norwegian, persian, portuguese, romanian, russian, sorani, spanish,
    swedish, turkish, thai 

    pattern analyzer

      用正则表达式将文本分割成sterms,默认的正则表达式是W+

    选择分词器

    put 192.168.199.170:9200/my_index
    {
        "settings": {
            "analysis": {
                "analyzer": {
                    "my_analyzer": {
                        "type": "whitespace"
                    }
                }
            }
        },
        "mappings": {
            "properties": {
                "name": {
                    "type": "text"
                },
                "team_name": {
                    "type": "text"
                },
                "position": {
                    "type": "text"
                },
                "play_year": {
                    "type": "long"
                },
                "jerse_no": {
                    "type": "keyword"
                },
                "title": {
                    "type": "text",
                    "analyzer": "my_analyzer"
                }
            }
        }
    }

    {
        "name": "库⾥",
        "team_name": "勇⼠",
        "position": "控球后卫",
        "play_year": 10,
        "jerse_no": "30",
        "title": "The best 3-points shooter is Curry!"
    }

    {
        "query": {
            "match": {
                "title": "Curry!"
            }
        }
    }

    常见中文分词器

    默认的分词standard

    {
        "analyzer": "standard",
        "text": "⽕箭明年总冠军" 
    }

    常见分词器

    • smartCN一个简单的中文或中英文混合文本的分词器
    • IK分词器,更智能更友好的中文分词器

    安装smartCN

    • sh elasticsearch-plugin install analysis-smartcn

    校验

      安装后重启

    {
        "analyzer": "smartcn",
        "text": "⽕箭明年总冠军" 
    }

    卸载

      sh elasticsearch-plugin remove analysis-smartcn

    IK分词器

      下载地址:点我直达

    安装,解压到plugins目录 

    然后重启 

    常见的字段类型

    数据类型

    • 核心数据类型
    • 复杂数据类型
    • 专用数据类型

    核心数据类型

    字符串

    • text:用于全文索引,该类型的字段将通过分词器进行分词
    • keyword:不分词,只能搜索该字段的完整的值

    数值型

    • long、integer、short、byte、double、float、half_float、scaled_float

    布尔

    • boolean

    二进制

    • binary:该类型的字段把值当做经过base64编码的字符串,默认不存储,且不可搜索

    范围类型

    1. 范围类型表示值是一个范围,而不是一个具体的值
    2. integer_range、float_range、long_range、double_range、date_range
    3. 比如age类型是integer_range,那么值可以是{"gte":20,"lte":40};搜索"term":{"age":21}可以搜索该值

    日期-date

      由于json类型没有date类型,所以es通过识别字符串是否符合format定义的格式来判断是否为date类型

      format默认为:strict_date_optional_time || epoch_millis

      格式

        "2022-01-01" "2022/01/01 12:10:30" 这种字符串格式

      从开始纪元(1970年1月1日0点)开始的毫秒数

    PUT 192.168.199.170:9200/nba/_mapping
    
    {
        "properties": {
            "name": {
                "type": "text"
            },
            "team_name": {
                "type": "text"
            },
            "position": {
                "type": "text"
            },
            "play_year": {
                "type": "long"
            },
            "jerse_no": {
                "type": "keyword"
            },
            "title": {
                "type": "text"
            },
            "date": {
                "type": "date"
            }
        }
    }
    POST 192.168.199.170:9200/nba/_doc/4
    
    {
        "name": "蔡x坤",
        "team_name": "勇⼠",
        "position": "得分后卫",
        "play_year": 10,
        "jerse_no": "31",
        "title": "打球最帅的明星",
        "date": "2020-01-01"
    }
    POST 192.168.199.170:9200/nba/_doc/5
    
    {
        "name": "杨超越",
        "team_name": "猴急",
        "position": "得分后卫",
        "play_year": 10,
        "jerse_no": "32",
        "title": "打球最可爱的明星",
        "date": 1610350870
    }
    POST 192.168.199.170:9200/nba/_doc/6
    
    {
        "name": "吴亦凡",
        "team_name": "湖⼈",
        "position": "得分后卫",
        "play_year": 10,
        "jerse_no": "33",
        "title": "最会说唱的明星",
        "date": 1641886870000
    }

    复杂数据类型

    数据类型 Array

    • ES中没有专门的数据类型,直接使用[]定义接口,数组中所有的值必须是同一种数据类型,不支持混合数据类型的数组
    • 字符串数组["one","two"]
    • 整数数组[1,2]
    • Object对象数组[{"name":"alex","age":18},{"name":"tom","age":18}]

    对象类型Object

    POST 192.168.199.170:9200/nba/_doc/8
    
    {
        "name": "吴亦凡",
        "team_name": "湖⼈",
        "position": "得分后卫",
        "play_year": 10,
        "jerse_no": "33",
        "title": "最会说唱的明星",
        "date": "1641886870",
        "array": [
            "one",
            "two"
        ],
        "address": {
            "region": "China",
            "location": {
                "province": "GuangDong",
                "city": "GuangZhou"
            }
        }
    }

    索引方式

    "address.region": "China",
    "address.location.province": "GuangDong",
    "address.location.city": "GuangZhou"
    POST 192.168.199.170:9200/nba/_search
    
    {
        "query": {
            "match": {
                "address.region": "china"
            }
        }
    }

    专用数据类型

    IP类型

      IP类型的字段用于存储IPv4和IPv6的地址,本质上是一个长整形字段

    POST 192.168.199.170:9200/nba/_mapping
    
    {
        "properties": {
            "name": {
                "type": "text"
            },
            "team_name": {
                "type": "text"
            },
            "position": {
                "type": "text"
            },
            "play_year": {
                "type": "long"
            },
            "jerse_no": {
                "type": "keyword"
            },
            "title": {
                "type": "text"
            },
            "date": {
                "type": "date"
            },
            "ip_addr": {
                "type": "ip"
            }
        }
    }
    PUT 192.168.199.170:9200/nba/_doc/9
    
    {
        "name": "吴亦凡",
        "team_name": "湖⼈",
        "position": "得分后卫",
        "play_year": 10,
        "jerse_no": "33",
        "title": "最会说唱的明星",
        "ip_addr": "192.168.1.1"
    }
    POST 192.168.199.170:9200/nba/_search
    
    {
        "query": {
            "term": {
                "ip_addr": "192.168.0.0/16"
            }
        }
    }

    kibana工具的安装和使用

    简介

      可视化工具kibana的安装和使用

    下载

    点我直达

    赋权限

     chown -R es:es781g /var/soft/kibana-7.8.1-linux-x86_64
    # 给用户组授权,语法:chown -R 用户:组名 es安装完整路径

    kibana.yml

    server.port: 5601   #kibana端口
    server.host: "10.0.0.169"    #绑定的主机IP地址
    elasticsearch.hosts: ["http://10.0.0.169:9200"]      #elasticsearch的主机IP
    kibana.index: ".kibana"     #开启此选项
    i18n.locale: "zh-CN"     #kibana默认文字是英文,变更成中文

    启动

    进⼊到⽂件夹的bin⽬录,执⾏sh kibana

    访问

    ip:5601

    简单使用

      后面示例,会大量使用该工具

    ES之批量导入数据

    简介

      手把手教你批量导入数据

    Bulk

      ES提供了一个叫bulk的API来进行批量操作

    批量导入

    数据

    {"index": {"_index": "book", "_type": "_doc", "_id": 1}}
    {"name": "权⼒的游戏"} {"index": {"_index": "book", "_type": "_doc", "_id": 2}}
    {"name": "疯狂的⽯头"}

    POST bulk

    curl -X POST "192.168.199.170:9200/_bulk" -H 'Content-Type: application/json' --data-binary @test

    ES之term的多种查询

    介绍

    • 单词级别查询
    • 这些查询通常用于结构化的数据,比如:number,data,keyword等,而不是对text
    • 也就是说,全文查询之前要先对文本内容进行分词,而单词级别的查询直接在相应字段的反向索引中精确查找,单词级别的查询一般用于数值、日期等类型的字段上

    准备工作

    1. 删除nba
    2. 新增nba索引
    {"mappings":{"properties":{"birthDay":{"type":"date"},"birthDayStr": {"type":"keyword"},"age":{"type":"integer"},"code": {"type":"text"},"country":{"type":"text"},"countryEn": {"type":"text"},"displayAffiliation":{"type":"text"},"displayName": {"type":"text"},"displayNameEn":{"type":"text"},"draft": {"type":"long"},"heightValue":{"type":"float"},"jerseyNo": {"type":"text"},"playYear":{"type":"long"},"playerId": {"type":"keyword"},"position":{"type":"text"},"schoolType": {"type":"text"},"teamCity":{"type":"text"},"teamCityEn": {"type":"text"},"teamConference": {"type":"keyword"},"teamConferenceEn":{"type":"keyword"},"teamName": {"type":"keyword"},"teamNameEn":{"type":"keyword"},"weight": {"type":"text"}}}}

    • 批量导入player

    Term query精准匹配查询

    POST nba/_search
    {
      "query": {
        "term": {
          "jerseyNo": "23"
        }
      },
      "from": 0,
      "size": 20
    }

    Exsit Query在特定的字段中查找非空值的文档(查找队名非空的球员)

    Prefix Query查找包含带有指定前缀term的文档(查找队名为Rock开头的球员)

    Wildcard Query支持通配符查询,*表示任意字符,?表示任意单个字符(查找火箭队的球员)

    Regexp Query正则表达式查询(查找火箭队的球员)

    Ids Query(查找id为1和2的球员)

    ES的范围查询

    查询指定字段在指定范围内包含值(日期、数字或字符串)的文档

      查找在nba打球在2年到10年以内的球员

    POST nba/_search
    {
      "query": {
        "range": {
          "playYear": {
            "gte": 2,
            "lte": 10
          }
        }
      },
      "from": 0,
      "size": 20
    }

    查找1999年到2020年出生的球员

    POST nba/_search
    {
      "query": {
        "range": {
          "birthDay": {
            "gte": "01/01/1999",
            "lte": "2020",
            "format": "dd/MM/yyyy||yyyy"
          }
        }
      },
      "from": 0,
      "size": 20
    }

    ES的布尔查询

    布尔查询

    type description
    must 必须出现在匹配文档中
    filter 必须出现在文档中,但是不打分
    must_not 不能出现在文档中
    should 应该出现在文档中

    must(查询名字叫做james的球员)

    POST nba/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "displayNameEn": "james"
              }
            }
          ]
        }
      },
      "from": 0,
      "size": 20
    }

    效果通must,但是不打分(查找名字叫做james的球员)

    POST nba/_search
    {
      "query": {
        "bool": {
          "filter": [
            {
              "match": {
                "displayNameEn": "james"
              }
            }
          ]
        }
      },
      "from": 0,
      "size": 20
    }

    must_not(查找名字叫做James的西部球员)

    POST nba/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "displayNameEn": "james"
              }
            }
          ],
          "must_not": [
            {
              "term": {
                "teamConferenceEn": {
                  "value": "Eastern"
                }
              }
            }
          ]
        }
      },
      "from": 0,
      "size": 20
    }

    组合起来含义:一定不在东部的james

    should(查找名字叫做James的打球时间应该在11到20年西部球员)

    即使匹配不到也返回,只是评分不同

    POST nba/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "displayNameEn": "james"
              }
            }
          ],
          "must_not": [
            {
              "term": {
                "teamConferenceEn": {
                  "value": "Eastern"
                }
              }
            }
          ],
          "should": [
            {
              "range": {
                "playYear": {
                  "gte": 11,
                  "lte": 20
                }
              }
            }
          ]
        }
      },
      "from": 0,
      "size": 20
    }

    如果minimum_should_match=1,则变成要查出名字叫做James的打球时间在11年到20年西部球员

    POST nba/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "displayNameEn": "james"
              }
            }
          ],
          "must_not": [
            {
              "term": {
                "teamConferenceEn": {
                  "value": "Eastern"
                }
              }
            }
          ],
          "should": [
            {
              "range": {
                "playYear": {
                  "gte": 11,
                  "lte": 20
                }
              }
            }
          ],
          "minimum_should_match": 1
        }
      },
      "from": 0,
      "size": 20
    }

    minimum_should_match代表了最小匹配经度,如果设置minimum_should_match=1,那么should语句中至少需要有一个条件满足

    ES的排序

    火箭队中按打球时间从大到小排序的球员

    POST nba/_search
    {
      "query": {
        "match": {
          "teamNameEn": "Rockets"
        }
      },
      "sort": [
        {
          "playYear": {
            "order": "desc"
          }
        }
      ], 
      "from": 0,
      "size": 20
    }

    火箭队中按打球时间从大到小,如果年龄相同则按照身高从高到低排序的球员

    POST nba/_search
    {
      "query": {
        "match": {
          "teamNameEn": "Rockets"
        }
      },
      "sort": [
        {
          "playYear": {
            "order": "desc"
          }
        },{
          "heightValue": {
            "order": "asc"
          }
        }
      ],
      "from": 0,
      "size": 20
    }

    ES聚合查询之指标聚合

    ES聚合查询是什么

    1. 聚合查询是数据库重要功能特性,完成对一个查询得到的数据集的聚合计算,如:找出某字段(或计算表达式的结果)的最大值,最小值,计算和,平均值等。ES作为搜索引擎,同样提供了强大的聚合分析能力
    2. 对一个数据集求最大、最小、和、平均值等指标的聚合,在ES中称为指标聚合
    3. 而关系型数据库中除了有聚合函数外,还可以对查询出的数据进行分组group by,再在组上进行指标聚合。在ES中称为“桶聚合

    max min sum avg

    求出火箭队球员的平均年龄

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "avgAge": {
          "avg": {
            "field": "age"
          }
        }
      },
      "size": 0
    }

    value_count统计非空字段的文档数

    求出火箭队中球员打球时间不为空的数量

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "countPlayerYear": {
          "value_count": {
            "field": "playYear"
          }
        }
      },
      "size": 0
    }

    查出火箭队有多少名球员

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      }
    }

    Cardinality值去重计数

    查出火箭队中年龄不同的数量

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "countAget": {
          "cardinality": {
            "field": "age"
          }
        }
      },
      "size": 0
    }

    stats统计count max min avg sum5个值

    查出火箭队球员的年龄stats

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "statsAge": {
          "stats": {
            "field": "age"
          }
        }
      },
      "size": 0
    }

    Extended stats比stats多4个统计结果:平方和、方差、标准差、平均值加/减两个标准差的区间

    查询火箭队球员的年龄Extend stats

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "extendStatsAge": {
          "extended_stats": {
            "field": "age"
          }
        }
      },
      "size": 0
    }

    Percentiles占比百分位对应的值统计,默认返回【1,5,25,50,75,95,99】分位上的值

    查出火箭的球员的年龄占比

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "pecentAge": {
          "percentiles": {
            "field": "age"
          }
        }
      },
      "size": 0
    }

    查出火箭的球员的年龄占比(指定分位值)

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "pecentAge": {
          "percentiles": {
            "field": "age",
            "percents": [
              20,
              50,
              75
            ]
          }
        }
      },
      "size": 0
    }

    ES聚合查询之桶聚合

    ES聚合分析是什么

    • 聚合分析是数据库中重要的功能特性,完成对一个查询的数据集中数据的聚合计算,如:找出字段(或计算表达式的结果)的最大值、最小值、计算和、平均值等。ES作为搜索引擎兼容数据库,同样提供了强大的聚合分析能力
    • 对一个数据集求最大、最小、和、平均值等指标的聚合,在ES中称为指标聚合
    • 而关系型数据库中除了有聚合函数外,还可以对查询出的数据进行分组group by,再在组上进行游标聚合。在ES中称为桶聚合

    Terms Aggregation根据字段项分组聚合

    火箭队根据年龄进行分组

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "aggsAge": {
          "terms": {
            "field": "age",
            "size": 10
          }
        }
      },
      "size": 0
    }

    Order分组聚合排序

    火箭队根据年龄进行分组,分组信息通过年龄从大到小排序(通过指定字段)

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "aggsAge": {
          "terms": {
            "field": "age",
            "size": 10,
            "order": {
              "_key": "desc"
            }
          }
        }
      },
      "size": 0
    }

    火箭队根据年龄进行分组,分组信息通过文档数从大到小排序(通过文档数)

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "aggsAge": {
          "terms": {
            "field": "age",
            "size": 10,
            "order": {
              "_count": "desc"
            }
          }
        }
      },
      "size": 0
    }

    每支球队按该队所有球员的平均年龄进行分组排序(通过分组指标值)

    POST /nba/_search
    {
      "query": {
        "term": {
          "teamNameEn": {
            "value": "Rockets"
          }
        }
      },
      "aggs": {
        "avgAge": {
          "avg": {
            "field": "age"
          }
        }
      },
      "size": 0
    }

    筛选分组聚合

    湖人和火箭队按球队平均年龄进行分组排序(指定值列表)

    POST /nba/_search
    {
      "aggs": {
        "aggsTeamName": {
          "terms": {
            "field": "teamNameEn",
            "include": [
              "Lakers",
              "Rockets",
              "Warriors"
            ],
            "exclude": [
              "Warriors"
            ],
            "size": 30,
            "order": {
              "avgAge": "desc"
            }
          },
          "aggs": {
            "avgAge": {
              "avg": {
                "field": "age"
              }
            }
          }
        }
      },
      "size": 0
    }

    湖人和火箭队按球队平均年龄进行分组排序(正则表达式匹配值)

    POST /nba/_search
    {
      "aggs": {
        "aggsTeamName": {
          "terms": {
            "field": "teamNameEn",
            "include": "Lakers|Ro.*|Warriors.*",
            "exclude": "Warriors",
            "size": 30,
            "order": {
              "avgAge": "desc"
            }
          },
          "aggs": {
            "avgAge": {
              "avg": {
                "field": "age"
              }
            }
          }
        }
      },
      "size": 0
    }

    Range Aggregation范围分组聚合

    NBA球员年龄按20,20-35,35这样分组

    POST /nba/_search
    {
      "aggs": {
        "ageRange": {
          "range": {
            "field": "age",
            "ranges": [
              {
                "to": 20
              },
              {
                "from": 20,
                "to": 35
              },
              {
                "to": 35
              }
            ]
          }
        }
      },
      "size": 0
    }

    NBA球员年龄按20,20-35,35这样分组(起别名)

    Date Range Aggregation时间范围分组聚合

    NBA球员按出生年月分组

    POST /nba/_search
    {
      "aggs": {
        "birthDayRange": {
          "date_range": {
            "field": "birthDay",
            "format": "MM-yyy",
            "ranges": [
              {
                "to": "01-1989"
              },
              {
                "from": "01-1989",
                "to": "01-1999"
              },
              {
                "from": "01-1999",
                "to": "01-2009"
              },
              {
                "from": "01-2009"
              }
            ]
          }
        }
      },
      "size": 0
    }

    Date Histogram Aggregation时间柱状图聚合

    按天、月、年等进行聚合统计。可按year(1y),quarter(1q),month(1M),week(1w),day(1d),hour(1h),minute(1m),second(1s)间隔聚合

    NBA球员按出生年分组

    POST /nba/_search
    {
      "aggs": {
        "birthday_aggs": {
          "date_histogram": {
            "field": "birthDay",
            "format": "yyyy",
            "interval": "year"
          }
        }
      },
      "size": 0
    }

    ES之query_string查询

    简介

      query_string查询,如果熟悉lucene的查询语法,我们可以直接用lucene查询语法写一个查询串进行查询,ES中接到请求后,通过查询解析器,解析查询串生成对应的查询。

    指定单个字段查询

    POST /nba/_search
    {
      "query": {
        "query_string": {
          "default_field": "displayNameEn",
          "query": "james OR curry"
        }
      }, 
      "size": 100
    }

    POST /nba/_search
    {
      "query": {
        "query_string": {
          "default_field": "displayNameEn",
          "query": "james AND harden"
        }
      }, 
      "size": 100
    }

    指定多个字段查询

    ElasticSearch的高级使用

    别名有什么用

      在开发中,随着业务需求的迭代,较老的业务逻辑就要面临更新甚至是重构,而对于es来说,为了适应新的业务逻辑,可能就要对原有的索引做一些修改,比如对某字段做调整,甚至是重构索引。而做这些操作的时候,可能会对业务造成影响,甚至是停机调整等问题。由此,es提供了索引别名来解决这些问题。索引别名就像一个快捷方式或软连接,可以指向一个或多个索引,也可以给任意一个需要索引名的API来使用。别名的应用为程序提供了极大地灵活性。

    查询别名

    GET /nba/_alias
    
    GET /_alias

    新增别名

    POST /_aliases
    {
      "actions": [
        {
          "add": {
            "index": "nba",
            "alias": "nba_v1.0"
          }
        }
      ]
    }

    删除别名

    方式一
    POST /_aliases
    {
      "actions": [
        {
          "remove": {
            "index": "nba",
            "alias": "nba_v1.0"
          }
        }
      ]
    }
    
    方式二
    DELETE /nba/_alias/nba_v1.0

    重命名别名

    POST /_aliases
    {
      "actions": [
        {
          "remove": {
            "index": "nba",
            "alias": "nba_v1.0"
          }
        },
        {
          "add": {
            "index": "nba",
            "alias": "nba_v2.0"
          }
        }
      ]
    }

    为多个索引指定一个别名

    POST /_aliases
    {
      "actions": [
        {
          "add": {
            "index": "nba",
            "alias": "nba_v2.0"
          }
        },{
          "add": {
            "index": "cba",
            "alias": "cba_v2.0"
          }
        }
      ]
    }

    为同个索引指定多个别名

    POST /_aliases
    {
      "actions": [
        {
          "add": {
            "index": "nba",
            "alias": "nba_v2.0"
          }
        },{
          "add": {
            "index": "nba",
            "alias": "cba_v2.2"
          }
        }
      ]
    }

    通过别名读索引

    当别名指定了一个索引,则查出一个索引

    当别名指定了多个索引,则查出多个索引

    GET /nba_v2.2

    通过别名写索引

    当别名指定了一个索引,则可以做写的操作

    POST /nba_v2.0/_doc/566
    {
      "countryEn": "Croatia",
      "teamName": "快船",
      "birthDay": 858661200000,
      "country": "克罗地亚",
      "teamCityEn": "LA",
      "code": "ivica_zubac",
      "displayAffiliation": "Croatia",
      "displayName": "伊维察 祖巴茨哥哥",
      "schoolType": "",
      "teamConference": "⻄部",
      "teamConferenceEn": "Western",
      "weight": "108.9 公⽄",
      "teamCity": "洛杉矶",
      "playYear": 3,
      "jerseyNo": "40",
      "teamNameEn": "Clippers",
      "draft": 2016,
      "displayNameEn": "Ivica Zubac",
      "heightValue": 2.16,
      "birthDayStr": "1997-03-18",
      "position": "中锋",
      "age": 22,
      "playerId": "1627826"
    }

    当别名指定了多个索引,可以指定写某个索引

    POST /_aliases
    {
      "actions": [
        {
          "add": {
            "index": "nba",
            "alias": "national_player",
            "is_write_index": true
          }
        },
        {
          "add": {
            "index": "cba",
            "alias": "national_player"
          }
        }
      ]
    }
    POST /national_player/_doc/566
    {
      "countryEn": "Croatia",
      "teamName": "快船",
      "birthDay": 858661200000,
      "country": "克罗地亚",
      "teamCityEn": "LA",
      "code": "ivica_zubac",
      "displayAffiliation": "Croatia",
      "displayName": "伊维察 祖巴茨妹妹",
      "schoolType": "",
      "teamConference": "⻄部",
      "teamConferenceEn": "Western",
      "weight": "108.9 公⽄",
      "teamCity": "洛杉矶",
      "playYear": 3,
      "jerseyNo": "40",
      "teamNameEn": "Clippers",
      "draft": 2016,
      "displayNameEn": "Ivica Zubac",
      "heightValue": 2.16,
      "birthDayStr": "1997-03-18",
      "position": "中锋",
      "age": 22,
      "playerId": "1627826"
    }

    ES之重建索引

    简介

      ElasticSearch是一个实时的分布式搜索引擎,为用户提供搜索服务,当我们决定存储某种数据时,在创建索引的时候需要将数据结构完整确定下来,于此同时索引的设定和很多固定配置将不能修改。当需要改变数据结构时,就需要重新建立索引,为此,Elastic团队提供了很多辅助工具帮助开发人员进行重建索引

    步骤

    1. nba取一个别名nba_latest,nba_latest作为对外使用
    2. 新增一个索引nba_20200810,结构复制于nba索引,根据业务要求修改字段
    3. 将nba数据同步至nba_20200810
    4. 给nba_20200810添加别名nba_latest,删除此处nba别名nba_latest
    5. 删除nba索引

    PUT /nba_20220810
    {
      "mappings": {
        "properties": {
          "age": {
            "type": "integer"
          },
          "birthDay": {
            "type": "date"
          },
          "birthDayStr": {
            "type": "keyword"
          },
          "code": {
            "type": "text"
          },
          "country": {
            "type": "keyword"
          },
          "countryEn": {
            "type": "keyword"
          },
          "displayAffiliation": {
            "type": "text"
          },
          "displayName": {
            "type": "text"
          },
          "displayNameEn": {
            "type": "text"
          },
          "draft": {
            "type": "long"
          },
          "heightValue": {
            "type": "float"
          },
          "jerseyNo": {
            "type": "keyword"
          },
          "playYear": {
            "type": "long"
          },
          "playerId": {
            "type": "keyword"
          },
          "position": {
            "type": "text"
          },
          "schoolType": {
            "type": "text"
          },
          "teamCity": {
            "type": "text"
          },
          "teamCityEn": {
            "type": "text"
          },
          "teamConference": {
            "type": "keyword"
          },
          "teamConferenceEn": {
            "type": "keyword"
          },
          "teamName": {
            "type": "keyword"
          },
          "teamNameEn": {
            "type": "keyword"
          },
          "weight": {
            "type": "text"
          }
        }
      }
    }

    将旧索引数据copy到新索引

    同步等待,接口将会在reindex结束后返回

    POST /_reindex
    {
      "source": {
        "index": "nba"
      },
      "dest": {
        "index": "nba_20220810"
      }
    }

    异步执行,如果reindex时间过长,建议加上“wait_for_completion=false”的参数条件,这样reindex将直接返回taskId

    POST /_reindex?wait_for_completion=false
    {
      "source": {
        "index": "nba"
      },
      "dest": {
        "index": "nba_20220810"
      }
    }

    替换别名

    POST /_aliases
    {
      "actions": [
        {
          "add": {
            "index": "nba_20220810",
            "alias": "nba_latest"
          }
        },
        {
          "remove": {
            "index": "nba",
            "alias": "nba_latest"
          }
        }
      ]
    }

    删除旧索引

    DELETE /nba

    通过别名访问新索引

    POST /nba_latest/_search
    {
      "query": {
        "match": {
          "displayNameEn": "james"
        }
      }
    }

    ES之refresh操作

    理想的搜索

      新的数据一添加到索引中立马就能搜索到,但是真实情况不是这样的

    我们使用链式命令请求,先添加一个文档,再立刻搜索

    curl -X PUT 192.168.199.170:9200/star/_doc/888 -H 'Content-Type:
    application/json' -d '{ "displayName": "蔡徐坤" }'
    curl -X GET localhost:9200/star/_doc/_search?pretty

    强制刷新

    curl -X PUT 192.168.199.170:9200/star/_doc/666?refresh -H 'Content-Type:
    application/json' -d '{ "displayName": "杨超越" }'
    curl -X GET localhost:9200/star/_doc/_search?pretty

    修改默认更新时间(默认时间是1s)

    PUT /star/_settings
    {
      "index": {
        "refresh_interval": "5s"
      }
    }

    将refresh关闭

    PUT /star/_settings
    {
      "index": {
        "refresh_interval": "-1"
      }
    }

    ES之高亮查询

    前言

      如果返回的结果集中很多符合条件的结果,那怎么能一眼就能看到我们想要的那个结果呢?比如下面网站所示的那样,我们搜索“科比”,在结果集中,将所有“科比”高亮显示?

    高亮查询

    POST /nba_latest/_search
    {
      "query": {
        "match": {
          "displayNameEn": "james"
        }
      },
      "highlight": {
        "fields": {
          "displayNameEn": {}
        }
      }
    }

    自定义高亮查询

    POST /nba_latest/_search
    {
      "query": {
        "match": {
          "displayNameEn": "james"
        }
      },
      "highlight": {
        "fields": {
          "displayNameEn": {
            "pre_tags": [
              "<h1>"
            ],
            "post_tags": [
              "</h1>"
            ]
          }
        }
      }
    }

    ES之查询建议

    查询建议是什么

      查询建议:是为了给用户提供更好的搜索体验。包括:词条检查,自动补全

    词条检查

    自动补全

    Suggester

    • Term suggester
    • Phrase suggester
    • Completion suggester

    字段

    text 指定搜索文本
    field 获取建议词的搜索字段
    analyzer 指定分词器
    size 每个词返回的最大建议词数
    sort

    如何对建议词进行排序,可用选项:

    score:先按评分排序、再按文档频率排、term顺序

    frequency:先按文档频率排,再按评分,term顺序排

    suggest_mode

    建议模式,控制提供建议词的方式:

    missing:仅在搜索的词项在索引中不存在时才提供建议词,默认值;

    popular:仅建议文档频率比搜索词项高的词

    always:总是提供匹配的建议词

    Term Suggester

      term词条建议器,对给输入的文本进行分词,为每个分词提供词项建议

    POST /nba_latest/_search
    {
      "suggest": {
        "my-suggestion": {
          "text": "jamse hardne",
          "term": {
            "suggest_mode": "missing",
            "field": "displayNameEn"
          }
        }
      }
    }

    Phrase suggester

      phrase短语建议,在term的基础上,会考量多个term之间的关系,比如是否同时出现在索引的原文里,相邻成都,以及词频等

    POST /nba_latest/_search
    {
      "suggest": {
        "my-suggestion": {
          "text": "jamse harden",
          "phrase": {
            "field": "displayNameEn"
          }
        }
      }
    }

    Completion suggester

      Completion完成建议

    POST /nba_latest/_search
    {
      "suggest": {
        "my-suggestion": {
          "text": "Miam",
          "completion": {
            "field": "teamCityEn"
          }
        }
      }
    }
  • 相关阅读:
    215. Kth Largest Element in an Array
    214. Shortest Palindrome
    213. House Robber II
    212. Word Search II
    210 Course ScheduleII
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    206. Reverse Linked List
    sql 开发经验
  • 原文地址:https://www.cnblogs.com/chenyanbin/p/13419497.html
Copyright © 2011-2022 走看看