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"
          }
        }
      }
    }
  • 相关阅读:
    ffmpeg中的sws_scale算法性能测试
    ffmpeg 新老接口问题及对照集锦
    入门视频采集与处理(显示YUV数据)
    RGB与YUV图像视频格式的相互转换
    ffmpeg视频解码简明教程
    FFmpeg源代码简单分析——sws_getContext()
    FFmpeg解码H264及swscale缩放详解
    我所理解的ThreadLocal
    网络通信Socket模块实现文件传输
    设计一个基于flask的高并发高可用的查询ip的http服务
  • 原文地址:https://www.cnblogs.com/chenyanbin/p/13419497.html
Copyright © 2011-2022 走看看