Java ES入门

踩坑实录

Posted by wxwmaple on March 17, 2021

简介

ES不是一个数据库,而是一个搜索引擎

优点:

  • 全文搜索:例如对于“我在北京的一家互联网公司工作”这样的数据,如果你搜索“北京”、“互联网”、“工作”这些关键词都能命中这条数据的话,这就是全文搜索,百度、Google都属于全文搜索。值得一提的是,ES的全文搜索对中文也有很好的支持(单是中文分词器就有很多种),绝对能够满足国内大多数人的全文搜索需求。

  • 自动建立索引:利用索引可实现高性能的复杂聚合查询,因此只要是存入ES的数据,无论再复杂的聚合查询也可以得到不错的性能。因此非常适合用于数据分析

缺点:

  • 字段类型无法修改:ES自动建立索引的前提是预先建立Mapping,Mapping中包含每个字段的类型信息,因此无法修改数据表的类型,只能删库重建
  • ES的性能低:自动建立索引消耗内存,影响速度,大数据量下64G内存+SSD基本是标配

ES的全文搜索特性使它成为构建搜索引擎的利器。除此之外,ES很好的支持了复杂聚合查询这一特点还使得ES非常适合拿来作数据分析使用。其实,ES还专门做了与自己配套的ELK套装,给你提供从日志收集到数据可视化分析的一条龙服务,绝对是构建高大上数据分析平台的利器。

竞品对比

如果你对数据的读写要求极高,并且你的数据规模不大,也不需要长期存储,选redis;

如果你的数据规模较大,对数据的读性能要求很高,数据表的结构需要经常变,有时还需要做一些聚合查询,选MongoDB;

如果你需要构造一个搜索引擎或者你想搞一个看着高大上的数据可视化平台,并且你的数据有一定的分析价值或者你的老板是土豪,选ElasticSearch;

如果你需要存储海量数据,连你自己都不知道你的数据规模将来会增长多么大,那么选HBase

img

安装&启动&配置

1
2
3
4
5
6
7
8
9
10
# 安装
$:wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.5.1.zip
$:unzip elasticsearch-5.5.1.zip
$:cd elasticsearch-5.5.1/

# 启动
$:./bin/elasticsearch

# 配置
sudo sysctl -w vm.max_map_count=262144 #进程中内存映射区域的最大数量,ES相当吃内存,需要多配置

基本概念

  • Index:相当于数据库

  • Type:相当于表

  • Document:相当于一条记录

  • Field:相当于一个字段

  • Node:一个服务器,用一个名字来标识

操作

对ES的操作统一经过HTTP请求完成。

我们要使用curl发送请求。curl取client url工具之意。

curl基本语法

  • GET:curl url

  • PUT:

    • 空参:curl -X PUT ‘localhost:9200/<indexname>’

    • 传参数:curl -X PUT -H “Content-Type: multipart/form-data;” -F “key1=val1” “YOUR_URI”

    • 传json:curl -X PUT -H “Content-Type: application/json” -d ‘{“key1”:”value”}’ “YOUR_URI”

    • 1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      
      curl -X PUT -H "Content-Type: application/json" "localhost:9200/news" -d\
      '\
      {\
        "mappings":{\
          "type1":{
            "properties":{
              "id":{
                "type":"text"
              },
              "url":{
                "type":"text"
              },
              "from":{
                "type":"text"
              },
              "hour_ip":{
                "type":"text"
              },
              "time":{
                "type":"text"
              },
              "1st_topic":{
                "type":"integer"
              },
              "main_keywords":{
                "type":"keyword"
              },
              "all_keywords":{
                "type":"keyword"
              },
              "segment_title":{
                "type":"text"
              },
              "segment_content":{
                "type":"text"
              }
            }
          }
        }
      }
      '
      
    • 传文件:curl -X POST “YOUR_URI” -F ‘file=@/file-path.csv’
  • POST:

    • 传参数:$ curl -d’login=emma&password=123’-X POST https://google.com/login

    • 传文件:$ curl -d ‘@data.txt’ https://google.com/login

    • 传json:

      1
      2
      3
      4
      
      curl --header "Content-Type: application/json" \
        --request POST \
        --data '{"username":"xyz","password":"xyz"}' \
        http://localhost:3000/api/login
      
  • DELETE:curl -XDELETE localhost:9200/索引*

索引(Index)

  • 创建索引:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    PUT <indexname>
    {
      "settings":{
        "index":{
          "number_of_shards":5,
          "number_of_replicas":1
        }
      }
    }
    

    其中使用了5个主分片,1个副分片。

    索引内任意一个文档都归属于一个主分片,所以主分片的数目决定着索引能够保存的最大数据量;

    一个副本分片只是一个主分片的拷贝。 副本分片作为硬件故障时保护数据不丢失的冗余备份,并为搜索和返回文档等读操作提供服务。

  • 查看全部索引:curl ‘localhost:9200/_cat/indices?v’

  • 查看索引信息:GET <indexname>

  • 查看索引某一项信息:GET <indexname>/_settings

  • 修改索引信息:和创建索引一样,用PUT

  • 删除索引:DELETE <indexname>

映射(Mapping)&类型(Type)

映射即mapping,规定好某一索引下的各个字段以及数据类型,便于ES更好地进行管理。虽然也可以不加映射,强行增加文本,但这样操作会出很多问题。

  • 查看映射:GET <indexname>/_mapping

查看映射,可以发现一个index的mapping下存在多种type,这说明可以把type理解成一张数据表的字段规范

文档(Document)

文档即一条具体的内容,相当于数据库中的记录

  • 新增文档:PUT <indexname>/type_name/id {your k-v lists}

  • 免id新增文档(自动分配):POST <indexname>/type_name/id {your k-v dicts}

  • 查看文档:GET <indexname>/<type_name>/<id>

  • 查看部分字段:GET <indexname>/<type_name>/<id>?_source=<key1>,<key2>

  • 修改文档:

    • 全量修改:直接PUT一个新的,同新增文档

    • 部分修改:

      1
      2
      3
      4
      
      POST <index_name>/<type_name>/<id>/_update
      {
        your k-v dicts
      }
      
  • 删除文档:DELETE <indexname>/<type_name>/<id>

最有用的是批量查询文档

  • 1
    2
    3
    4
    5
    
    GET <index_name>/<type_name>/_mget
    {
      "ids":["1", "2"]
      }
    }