• ElasticSearch-全文检索快速入门


    ElasticSearch-全文检索快速入门

    官网https://www.elastic.co/cn/what-is/elasticsearch

    **全文搜索属于最常见的需求,开源的 Elasticsearch 是目前全文搜索引擎的首选。
    它可以快速地储存、搜索和分析海量数据。**维基百科、Stack Overflow、Github 都采用它。

    Elastic 是 Lucene 的封装,提供了 REST API (天然的跨平台)的操作接口,开箱即用。

    官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

    官方中文:https://www.elastic.co/guide/cn/elasticsearch/guide/current/foreword_id.html

    社区中文:
    https://es.xiaoleilu.com/index.html
    http://doc.codingdict.com/elasticsearch/0/

    是什么?

    一个全文搜索引擎。

    有什么用?

    海量数据全文搜索、存储、分析。

    解决什么问题?

    当下技术存储数据查找搜索慢。

    场景

    • 大量数据搜索
    • 日志记录分析

    image-20221103174219874

    在8.0版本正式删除类型概念。

    #elasticSearch

    一、基本概念

    1、Index(索引)

    相当于MySQL的库概念

    2、Type(类型)

    相当于MySQL的Table概念

    3、Document(文档)

    文档为 JSON 格式,Document 就像是 MySQL 中的某个 Table 里面的内容

    4、倒排索引机制

    使用分词技术分词,存储分词和相关文档记录。能极大提高相关查询效率。

    image-20221028184448792

    二、Docker 安装 ES

    1、下载镜像文件

    docker pull elasticsearch:7.4.2
    存储和检索数据
    docker pull kibana:7.4.2
    可视化检索数据
    
    • 1
    • 2
    • 3
    • 4

    2、创建实例

    1.ElasticSearch

    # 创建ES配置目录
    mkdir -p /home/hacah/dockerdata/elasticsearch/config
    mkdir -p /home/hacah/dockerdata/elasticsearch/data
    echo "http.host: 0.0.0.0" >> /home/hacah/dockerdata/elasticsearch/config/elasticsearch.yml
    # 保证权限
    chmod -R 777 /home/hacah/dockerdata/elasticsearch/
    # 启动
    docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
    -e "discovery.type=single-node" \
    -e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
    -v /home/hacah/dockerdata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
    -v /home/hacah/dockerdata/elasticsearch/data:/usr/share/elasticsearch/data \
    -v /home/hacah/dockerdata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
    -d elasticsearch:7.4.2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    特别注意:
    -e ES_JAVA_OPTS=“-Xms64m -Xmx512m” \ 测试环境下,设置 ES 的初始内存和最大内存。

    2.Kibana

    docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.31.158:9200 -p 5601:5601 \
    -d kibana:7.4.2
    
    • 1
    • 2

    三、基础使用

    1._cat使用
    • GET /_cat/nodes:查看所有节点
    • GET /_cat/health:查看 es 健康状况
    • GET /_cat/master:查看主节点
    • GET /_cat/indices:查看所有索引
    2、索引一个文档(保存)

    指定保存在哪个索引的哪个类型下,指定用哪个唯一标识。

    PUT customer/external/1 是在 customer 索引下的 external 类型下保存 1 号数据

    保存可以使用PUT或POST请求

    POST :可以新增可以修改。如果不指定 id,会自动生成 id,指定 id 就会修改这个数据,并新增版本号。

    # 不指定id
    http://192.168.31.158:9200/customer/external
    # 指定id
    http://192.168.31.158:9200/customer/external/2
    
    • 1
    • 2
    • 3
    • 4

    PUT: 可以新增可以修改,但一定需要指定id,不指定 id 会报错。由于 PUT 需要指定 id,我们一般都用来做修改操作,请求url方式与post一样。

    3、查询文档

    GET customer/external/1

    {
       
        "_index": "customer",//在哪个索引
        "_type": "external",//在哪个类型
        "_id": "1",//记录 id
        "_version": 2,//版本号
        "_seq_no": 1,//并发控制字段,每次更新就会+1,用来做乐观锁
        "_primary_term": 1,//同上,主分片重新分配,如重启,就会变化
        "found": true,
        "_source": {
         //真正的内容
            "name": "John Doe"
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    4、更新文档

    POST有两种操作:

    POST customer/external/1/_update
    {
        "doc":{  
        	"name": "John de"  // 更新内容
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其中的doc结构是固定的,更新的数据在其中。

    第二种:

    POST customer/external/1
    {
        	"name": "John dt"  // 更新内容
    }
    
    • 1
    • 2
    • 3
    • 4

    如何确定使用哪种呢?

    基于场景,对于大并发更新,不带 update;

    对于大并发查询偶尔更新,带 update;对比更新,重新计算分配规则。

    PUT只能使用不带_update的更新且用法与POST类似。

    5、删除文档&索引
    # 删除文档
    DELETE customer/external/1
    # 删除索引
    DELETE customer
    
    • 1
    • 2
    • 3
    • 4
    6、bulk 批量 API

    bulk用于批量操作,使用操作如下:

    POST customer/external/_bulk
    { action: { metadata }}\n
    { request body}\n
    
    • 1
    • 2
    • 3

    url添加_bulk,请求体中两条数据为一个操作。

    比如:

    POST /_bulk
    { "delete": { "_index": "website", "_type": "blog", "_id": "123" }}
    { "create": { "_index": "website", "_type": "blog", "_id": "123" }}
    { "title":"My first blog post" }
    { "index":{ "_index": "website", "_type": "blog" }}
    { "title":"My second blog post" }
    { "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict" : 3} }
    { "doc" : {"title" : "My updated blog post"} }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在kibana执行以上指令。

    bulk API 以此按顺序执行所有的 action(动作)。如果一个单个的动作因任何原因而失败,
    它将继续处理它后面剩余的动作。当 bulk API 返回时,它将提供每个动作的状态。

    7、样本测试数据

    顾客银行账户信息的虚构的 JSON文档样本

    POST bank/account/_bulk

    https://github.com/elastic/elasticsearch/blob/7.4/docs/src/test/resources/accounts.json

    执行上面的数据指令。

    四、进阶检索

    1、SearchAPI

    ES 支持两种基本方式检索 :

    • 一个是通过使用 REST request URI
      发送搜索参数(uri+检索参数)
    • 另一个是通过使用
      REST request body 来发送它们(uri+请求体)
    检索信息

    uri参数检索

    # 检索 bank 下所有信息,包括 type 和 docs
    GET bank/_search
    # 请求参数方式检索
    GET bank/_search?q=*&sort=account_number:asc
    
    # 得到的响应属性解析
    took - Elasticsearch 执行搜索的时间(毫秒)
    time_out - 告诉我们搜索是否超时
    _shards - 告诉我们多少个分片被搜索了,以及统计了成功/失败的搜索分片
    hits - 搜索结果
    hits.total - 搜索结果
    hits.hits - 实际的搜索结果数组(默认为前 10 的文档)
    sort - 结果的排序 key(键)(没有则按 score 排序)
    score 和 max_score –相关性得分和最高得分(全文检索用)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    请求体进行检索

    GET bank/_search
    {
       
        "query": {
       
        	"match_all": {
       }
        },
        "sort": [
        	{
       
        	"account_number": {
       
        		"order": "desc"
        		}
        	}
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    使用请求工具就改为POST请求。

    2、Query DSL

    Elasticsearch 提供了一个可以执行查询的 Json 风格的 DSL(domain-specific language 领域特
    定语言)。这个被称为 Query DSL。

    一个查询语句的典型结构:

    {
        QUERY_NAME: {
            ARGUMENT: VALUE,
            ARGUMENT: VALUE,...
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果是针对某个字段,那么它的结构如下:

    {
        QUERY_NAME: {
            FIELD_NAME: {
                ARGUMENT: VALUE,
                ARGUMENT: VALUE,...
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用例子:

    GET bank/_search
    {
        "query": {
        	"match_all": {}
        },
        "from": 0,
        "size": 5,
        "sort": [
            {
            "account_number": {
            	"order": "desc"
             }
            }
        ],
        "_source": ["age","balance"]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • query 定义如何查询,

    • match_all 查询类型【代表查询所有的所有】,es 中可以在 query 中组合非常多的查
      询类型完成复杂查询

    • 除了 query 参数之外,我们也可以传递其它的参数以改变查询结果。如 sort,size

    • from+size 限定,完成分页功能

    • sort 排序,多字段排序,会在前序字段相等时后续字段内部排序,否则以前序为准

    • "_source"定义返回字段

    1 match(匹配查询)

    可以分为数值匹配和字符串全文索引,数值匹配会查询完全相同的数据,而字符串全文索引会按分词查询相关度的数据(需要使用单词查询)。

    基本类型(非字符串),精确匹配:

    GET bank/_search
    {
      "query": {
        "match": {
          "balance": "16418"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    字符串全文索引

    GET bank/_search
    {
      "query": {
        "match": {
          "address": "Road 263"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    查询出相关数据与相关度得分。

    2 match_phrase(短语匹配)

    短语匹配会把查询值当做不可分割的整体查询,即对比match来说不进行分词查询,把短语作为整体查询出相关度。

    GET bank/_search
    {
      "query": {
        "match_phrase": {
          "address": "Aviation Road"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    查询包含Aviation Road的数据。

    3 multi_match(多字段匹配)

    match的多字段版本

    GET bank/_search
    {
       
      "query": {
       
        "multi_match": {
       
          "query": "Road",
          "fields": ["address", "state"]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    查询 address或者state两个字段的匹配Road数据。

    4 bool(复合查询)

    复合语句可以合并任何其它查询语句,包括复合语句,复合语句之间可以互相嵌套,可以表达非常复杂的逻辑。

    image-20221103163435539

    • must:必须达到 must 列举的所有条件
    • should:应该达到 should 列举的条件,如果达到会增加相关文档的评分,不改变查询结果
    • must_not 必须不是指定的情况
    GET bank/_search
    {
       
      "query":
    • 1
    • 2
    • 3
  • 相关阅读:
    Docker实战一
    vue中含有iframe的页面如何避免路由切换时keep-alive不起作用
    基于物联网的室内环境检测云系统设计(树莓派RPI、Arduino、智能家居、RFID、APP)
    python性能提升之字符串拼接、字节流拼接
    Linux之shell条件测试
    LVS-NAT模式部署
    uView2 LineProgress进度太小时显示不全的一种解决办法
    vmware安装MacOS以及flutter遇到的问题
    记录keras库中导入函数找不到的问题
    git还原过程中如何显示更详细的日志
  • 原文地址:https://blog.csdn.net/hwh295/article/details/127691426