文章目录

  • 备注、必看
  • ElasticSearch 和 Solr 介绍,对比
  • ElasticSearch 7.8.
    • 官网
    • 基本概念
      • Cluster(集群) 与 Node(节点)
      • Index -索引
        • 索引结构
        • 索引原理:Inverted Index(倒排索引)
        • 索引分片
      • Type(逐渐弃用)
      • Document -文档
        • 文档结构
    • 节点用法:冷热数据分离
  • http操作ES
    • 集群 操作
    • 索引 操作
    • 索引-映射 操作
    • 文档 操作 CRUD
      • !!!查询
        • 查询语法 Query DSL
          • 多索引查询
          • 统计总数据条数
  • 插件:IK中文分词器
    • 分词器字典
    • 分词算法
  • 工具
    • 1. 可视化工具 ElasticSearch-head
    • 2. 数据分析展示 Kibana
  • springboot集成
    • TransportClient
    • RestClient

备注、必看

文章背景:

之前没接触过搜索引擎,然后接手了一个es的项目,临时抱佛脚东拼西凑查资料把项目支持下去了,把过程中查的资料与自己的一些操作整理了一下发了出来

不适合新人入门学习,也不适合专家参考
如果你也是被迫从都不知道搜索引擎就要在项目快速使用es,那可以快速的过一遍本文有个基础的使用概念


ElasticSearch 和 Solr 介绍,对比

  • ElasticSearch和Solr 都是封装了Lucene; 实现 全文搜索 功能

ElasticSearch

  • 解压即用
  • 提供RESTful API接口,只支持json
  • 注重核心的搜索功能,在处理大数据时性能更好
  • 刚兴起,更新快

Solr

  • 安装稍微复杂
  • 提供类似 webservice的API接口,支持json,xml,csv
  • 有很多额外的功能,适合传统搜索
  • 使用成熟,用户多

ElasticSearch 7.8.

官网

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

  • 学习网站
    https://www.knowledgedict.com/tutorial/elasticsearch-intro.html

基本概念

关系型数据库与ElasticSearch对比

向Elasticsearch中存储数据,其实就是向es中的index下面的type中存储json类型的数据。

Cluster(集群) 与 Node(节点)

Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例。

单个 Elastic 实例称为一个节点(node)。

一组节点构成一个集群(cluster)。

  • 主节点
  • 数据节点
  • 客户端节点

Index -索引

  • Elastic 数据管理的顶层单位就叫做 Index(索引), 含义类似单个数据库
  • Index (即数据库)的名字必须是小写。

索引结构

  1. aliases
  2. mappings 映射,定义type
  3. settings
{"users" : {"aliases" : { 别名 },"mappings" : {type-name : {"properties" : {"age" : {"type" : "integer"},"name" : {"type" : "keyword"}}}},"settings" : { 索引设置 }}
}

索引原理:Inverted Index(倒排索引)

  • Elastic 会索引所有字段,经过处理后写入一个Inverted Index
  • 通过文档内容去管理主键ID
  • 可以过滤无关数据,提高效率,适用于快速全文搜索

索引:通过有序的key去找value
正排索引:key=文档,value=关键词
倒排索引:key=关键词,value=文档

索引分片

单个节点由于物理机硬件限制 大小是有限的。一个索引如果特别大 导致在单个节点放不下。

索引分成多个分片,分片可以存储在集群中不同节点

  • 主分片
    分片并非将所有的数据都放在一起,多个主分片合起来才是所有的数据

以默认的5个主分片为例,ES会将数据均衡的存储到5个分片上,
也就是这5个分片的数据并集才是整个数据集,
这5个分片会按照一定规则分配到不同的ES Node上。这样的5个分片叫主分片。

  • 从分片
    从分片只是主分片的一个副本,它用于提供数据的冗余副本
    默认设置是一个主分片会有一个从分片,那么就有5个从分片,那么默认配置会产生10个分片(5主5从)就散布在所有的Node上

Type(逐渐弃用)

用来定义数据结构

  • 例:该type 有age和name两个字段,age字段是integer类型,name是keyword类型
      type-name : {"properties" : {"age" : {"type" : "integer"},"name" : {"type" : "keyword"}}}
  • 用法:

    1. 一个索引 里 有多种type,就可以存储多种类型的数据
    2. 多个索引里有同一种 type,可以只根据type全部查询出来

5.x 支持多种type
6.x 只能有一种type
7.x 版本基本不用
8.x 版本舍弃

Document -文档

  • Index 里面单条的记录称为 Document(文档)
  • 使用 JSON 格式表示
  • 搜索数据的最小单元

文档结构

{"_index": 所属索引,"_type": 所属type,"_id": 唯一id,"_version": 版本,"_score": 相关度评分,"_source": {"name": "张三","age": "18"}
}

节点用法:冷热数据分离

https://blog.csdn.net/laoyang360/article/details/102539888


http操作ES

集群 操作

查看集群信息

  • GET http://IP:9200/
{"name": "eZ3dEvq","cluster_name": "ElasticSearch","cluster_uuid": "唯一id","version": {"number": "5.5.3","build_hash": "9305a5e","build_date": "2017-09-07T15:56:59.599Z","build_snapshot": false,"lucene_version": "6.6.0"},"tagline": "You Know, for Search"
}

索引 操作

method url 作用
PUT http://IP:9200/{索引名称} 创建索引
GET http://IP:9200/_cat/indices?v 查看所有索引
GET http://IP:9200/{索引名称} 查看单个索引
DELETE http://IP:9200/{索引名称} 删除索引
{".kibana"【索引名】: {"aliases"【别名】: {},"mappings"【映射 mappings信息 :修改字段和类型】: {"timelion-sheet":{}},"settings"【settings信息 :修改分片和副本数】: {"index"【索引】: {"creation_date"【创建时间】: "1614265373911","number_of_shards"【主分片数量】: "1","number_of_replicas"【副分片数量】: "1","mapper": {"dynamic": "false"},"provided_name"【名称】: ".kibana""uuid"【唯一标识】: "eI5wemRERTumxGCc1bAk2A","version"【版本】: {"created": "7080099"}}}}
}

索引-映射 操作

  • 创建映射
curl -X PUT 'IP:9200/shopping/_mapping' -d '
{"properties": {"字段名":{"type": " 类型 :字符串/数字/日期/数组/对象【text、keyword(不可分词)、long、short、date、integer、Array、object】","index": 是否索引【是索引就可以用来进行搜索】,"store": false,【是否将数据进行独立存储】,"analyzer": "分词器"},"name":{"type": "text","index": true},"sex":{"type": "text","index": false},"age":{"type": "long","index": false}}
}'

文档 操作 CRUD

method url 作用
POST http://IP:9200/{索引名称}/{文档名称} 创建文档(随机id)
POST http://IP:9200/{索引名称}/{文档名称}/{id} 创建文档(指定id)
GET http://IP:9200/{索引名称}/{文档名称}/{id} 查看文档
POST http://IP:9200/{索引名称}/{文档名称}/{id} 更新文档=创建覆盖文档
POST http://IP:9200/{索引名称}/{文档名称}/{id}/_update 更新字段
DELETE http://IP:9200/{索引名称}/{文档名称}/{id} 删除文档
POST http://IP:9200/{索引名称}/_delete_by_query 条件删除文档
  • 创建文档
curl -X POST 'IP:9200/shopping/phone' -d '
{"title":"小米手机","category":"小米10","price":3999.00
}'
# 服务器响应结果
{"_index"【索引】: "shopping","_type"【 类型-文档 】: "phone","_id"【唯一标识】: "Xhsa2ncBlvF_7lxyCE9G", #可以类比为 MySQL 中的主键,随机生成"_version"【版本】: 1,"result"【结果】: "created", #这里的 create 表示创建成功"_shards"【分片】: {"total"【分片 - 总数】: 2,"successful"【分片 - 成功】: 1,"failed"【分片 - 失败】: 0},"_seq_no": 0,"_primary_term": 1
}
  • 更新字段:单价改为4000
curl -X POST 'IP:9200/shopping/phone/Xhsa2ncBlvF_7lxyCE9G/_update' -d '
{"doc": {"price":4000.00}
}'
  • 删除指定id的文档
curl -X DELETE 'IP:9200/shopping/phone/{id}'
  • 条件删除文档:删除单价为4000的文档
curl -X POST 'IP:9200/shopping/phone/_delete_by_query' -d '
{"query":{"match":{"price":4000.00}}
}'

!!!查询

查询语法 Query DSL

_search 为endpoint,主要分为字段类查询和复合查询。

  1. 字段类查询:只针对某一个字段进行查询,如match、term等;

    1. 单词匹配:不进行分词处理,直接匹配
    2. 全文匹配:先对查询语句进行分词处理,然后再去匹配
  2. 复合查询:可以进行一个或多个字段的查询,如bool查询等.
POST /_search
{"query":{"查询类型":{"查询条件":"查询条件值"}}
}

查询类型包括

  • 全文匹配

    1. match_all 查询所有
    2. match 匹配查询
    3. multi_match 多字段匹配查询
    4. match_phrase 有顺序要求
    5. query_string
    6. simple_query_string
  • 单词匹配
    1. term 不分词
    2. terms
    3. range 用于date或number类型的字段范围查询
  • 复合查询、组合查询
    1. bool

      1. must 返回的文档必须满足must子句的条件,并且参与计算分值
      2. must_not 返回的文档必须不满足定义的条件
      3. filter 返回的文档必须满足filter子句的条件, 不计算分值
      4. should 如果没有must或者filter,有一个或者多个should子句,那么只要满足一个就可以返回

搜索案例详见 :
https://blog.csdn.net/xyc1211/article/details/120349794

多索引查询

一个索引可以接受多个 alias 别名,而一个别名也可以映射到多个索引

索引1,索引2

统计总数据条数
GET /{index}/_count

插件:IK中文分词器

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

  • 作用:把一段中文,按照分词器字典,拆分成一个个关键词

  • 使用方法:
    下载解压ik,放在es的plugins目录下,启动es会自动加载ik插件

分词器字典

默认字典:ik/config/*.dic
可以在 ik/config/IKAnalyzer.cfg.xml 文件 配置扩展字典

分词算法

  1. ik_smart 最少切分
  2. ik_max_word 最细粒度划分
curl -X PUT 'localhost:9200/accounts' -d '
{"mappings": {"person": {"properties": {"desc": {"type": "张三是谁啊","analyzer": "ik_max_word","search_analyzer": "ik_smart"}}}}
}'
  • analyzer:字段文本的分词器
  • search_analyzer:搜索词的分词器

工具

1. 可视化工具 ElasticSearch-head

https://github.com/mikewuhao/es-head

  • 安装

    1. 可以独立安装使用(需要前端npm环境)
    2. 也可以通过浏览器插件使用
  • 使用

    1. 连接es集群,可以 查看集群中的索引,索引中的类型,类型中的字段

    2. 查看文档
    3. 查询搜索

2. 数据分析展示 Kibana

https://blog.csdn.net/xyc1211/article/details/117397854


springboot集成

es官网也提供了ES Java RestClient的方式来访问es

        <!-- es --><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>5.5.3</version></dependency><!-- es 客户端 --><dependency><groupId>org.elasticsearch.client</groupId><artifactId>rest</artifactId><version>5.5.3</version></dependency>

Elasticsearch(ES)有两种连接方式:

  1. TransportClient
  2. RestClient。

都是线程安全的,都应该使用单例。

TransportClient

  1. 通过TCP方式访问ES
  2. 该transport node并不会加入集群,而是简单的向ElasticSearch集群上的节点发送请求。
  3. 只支持java
  4. Elasticsearch计划在Elasticsearch 7.0中弃用TransportClient,在8.0中完全删除
    import java.net.InetAddress;import org.elasticsearch.action.get.GetResponse;import org.elasticsearch.client.transport.TransportClient;import org.elasticsearch.common.settings.Settings;import org.elasticsearch.common.transport.InetSocketTransportAddress;import org.elasticsearch.transport.client.PreBuiltTransportClient;public class TestEsClient {public static void main(String[] args) {try {//设置集群名称Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();//创建clientTransportClient client = new PreBuiltTransportClient(settings);TransportAddress transportAddress = new TransportAddress(InetAddress.getByName("127.0.0.1"), Integer.valueOf(9300));client.addTransportAddress(transportAddress);//Get查询: 根据 (索引名称、类型、id)获取文档GetResponse response = client.prepareGet("INDEX", "TYPE", "id").execute().actionGet();//输出结果System.out.println(response.getSourceAsString());//关闭clientclient.close();} catch (Exception e) {e.printStackTrace();}}}
  • 组合查询
    转载至 https://blog.csdn.net/fanrenxiang/article/details/86509688
//复合查询-Bool查询public void boolDsl() {//Bool QueryBoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//电影名称必须包含我不是药神经过分词后的文本,比如我、不、是、药、神boolQueryBuilder.must(QueryBuilders.matchQuery(MovieSearch.NAME, "我不是药神"));//排除导演是张三的电影信息boolQueryBuilder.mustNot(QueryBuilders.termQuery(MovieSearch.DIRECTORS, "张三"));//别名中应该包含药神经过分词后的文本,比如药、神boolQueryBuilder.should(QueryBuilders.matchQuery(MovieSearch.ALIAS, "药神"));//评分必须大于9(因为es对filter会有智能缓存,推荐使用)boolQueryBuilder.filter(QueryBuilders.rangeQuery(MovieSearch.SCORE).gt(9));//name、actors、introduction、alias、label 多字段匹配"药神",或的关系boolQueryBuilder.filter(QueryBuilders.multiMatchQuery("药神", MovieSearch.NAME, MovieSearch.ACTORS, MovieSearch.INTRODUCTION, MovieSearch.ALIAS, MovieSearch.LABEL));String[] includes = {MovieSearch.NAME, MovieSearch.ALIAS, MovieSearch.SCORE, MovieSearch.ACTORS, MovieSearch.DIRECTORS, MovieSearch.INTRODUCTION};SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(INDEX).setTypes(TYPE).setQuery(boolQueryBuilder).addSort(MovieSearch.SCORE, SortOrder.DESC).setFrom(0).setSize(10).setFetchSource(includes, null);SearchResponse searchResponse = searchRequestBuilder.get();if (!RestStatus.OK.equals(searchResponse.status())) {return;}for (SearchHit searchHit : searchResponse.getHits()) {String name = (String) searchHit.getSource().get(MovieSearch.NAME);//TODO}}

RestClient

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.14/java-rest-high-search.html

  1. 通过http API 访问ES
  2. 没有语言限制。

ES提供了两个JAVA REST client 版本

  • Java Low Level REST Client: 低级别的REST客户端,通过http与集群交互,用户需自己编组请求JSON串,及解析响应JSON串。兼容所有ES版本。
  • Java High Level REST Client: 高级别的REST客户端,基于低级别的REST客户端,增加了编组请求JSON串、解析响应JSON串等相关api。使用的版本需要保持和ES服务端的版本一致,否则会有版本问题。

官方推荐使用高级版,低级版需要自己准确记住api。

import org.elasticsearch.client.RestClient;//初始化RestClient实例static  RestClient restClient = RestClient.builder(new HttpHost("192.168.10.5", 9200, "http"),new HttpHost("192.168.10.6", 9200, "http"),new HttpHost("192.168.10.7", 9200, "http")).build()
//同步调用 Rest Api方法
public Response performRequest(String method, String endpoint, Header... headers) throws IOException
public Response performRequest(String method, String endpoint, Map<String, String> params, Header... headers) throws IOException
public Response performRequest(String method, String endpoint, Map<String, String> params,HttpEntity entity, Header... headers) throws IOException// (1) 执行一个基本的方法,验证es集群是否搭建成功Response response = restClient.performRequest("GET", "/", Collections.singletonMap("pretty", "true"));System.out.println(EntityUtils.toString(response.getEntity()));
//输出结果:
{"name" : "nd2","cluster_name" : "search","version" : {"number" : "2.3.4","build_hash" : "e455fd0c13dceca8dbbdbb1665d068ae55dabe3f","build_timestamp" : "2016-06-30T11:24:31Z","build_snapshot" : false,"lucene_version" : "5.5.0"},"tagline" : "You Know, for Search"
}// (2)验证es的某个索引是否存在
Response response = restClient.performRequest("HEAD","/product/pdt",Collections.<String, String>emptyMap());
System.out.println(response.getStatusLine().getReasonPhrase().equals("OK"));
//输出结果:
true// (3) 删除某个索引的指定条件的数据Map<String, String> paramMap = new HashMap<String, String>();paramMap.put("q", "id:"+id);paramMap.put("pretty", "true");
Response response = restClient.performRequest("DELETE","product/pdt/_query", paramMap);
System.out.println(EntityUtils.toString(response.getEntity()));
//输出结果:
{"took" : 0,"timed_out" : false,"_indices" : {"_all" : {"found" : 1,"deleted" : 0,"missing" : 0,"failed" : 0}},"failures" : [ ]
}// 用SearchSourceBuilder来构造 查询条件
String endPoint = '/index/_search?ignore_unavailable=true'SearchSourceBuilder requestSourceBuilder = new SearchSourceBuilder();
requestSourceBuilder.from(from);
requestSourceBuilder.size(size);HttpEntity entity = new NStringEntity(requestSourceBuilder.toString(), ContentType.APPLICATION_JSON);HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory = new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(BUFFER_SIZE);
Response response = restClient.performRequest("GET", endPoint,Collections.<String, String>emptyMap(),entity, consumerFactory);

ElasticSearch(ES)相关推荐

  1. [Elasticsearch] es 6.6 编译报错 SSL peer shut down incorrectly

    1.概述 前提:[Elasticsearch] es 6.6 编译报错 java.net.ConnectException: Operation timed out Mac 编译es 6.8 报错 [ ...

  2. ElasticSearch (ES)学习之路(二)Win10安装ES,可视化界面,Kibanna

    ElasticSearch (ES)学习之路(二)Win10安装ES,可视化界面,Kibanna 我前一段时间学习的时候ES 还是7.6.x 现在看ES 官网已经到了7.8.X了,迭代维护的速度还是挺 ...

  3. ElasticSearch es 插件开发

    ElasticSearch es 插件开发 1. 插件分类 API Extension Plugins API扩展插件 通过添加新的API或功能向Elasticsearch添加新功能,通常与搜索或映射 ...

  4. Elasticsearch(ES)的下载与安装

    Elasticsearch(ES)的下载与安装 1.安装 Java 在安装 Elasticsearch 之前,我们需要安装并配置好 JDK, 设置好环境变量 $JAVA_HOME. Elasticse ...

  5. ElasticSearch -- ES 7.x 集群版安装部署

    向导 1. ElasticSearch 1.下载 2.配置 3.查看启动状态 4.注册宕机.开机自启 5.如果磁盘是SSD,建议修改IO调度算法 6.SSD磁盘,关闭numa绑核.hugepage 2 ...

  6. elasticsearch(es)分布式全文检索引擎 简介

    0. 带着问题上路-ES是如何产生的? (1)思考:大规模数据如何检索? 如:当系统数据量上了10亿.100亿条的时候,我们在做系统架构的时候通常会从以下角度去考虑问题: 1)用什么数据库好?(MyS ...

  7. 使用canal同步MySQL数据到Elasticsearch(ES)

    目录 1.功能及使用场景 1.1.功能介绍 1.2.使用场景 2.需求引入 3.canal文件下载及准备 3.1 下载文件 3.2 准备文件 4.deployer安装及效果测试 4.1.deploye ...

  8. [Elasticsearch] es 6.6 编译报错 java.net.ConnectException: Operation timed out

    1.概述 Mac 编译es 6.8 报错 [lcc@lcc ~/IdeaProjects/source_code/elasticsearch]$ ./gradlew assemble Download ...

  9. Elasticsearch(ES) 基本知识

    ES 学习笔记 Linux 安装ES及Kibana(7.17.4版本) ES基本使用 ES是一个基于Apache的开源索引库Lucene而构建的 开源.分布式.具有RESTful接口的全文搜索引擎, ...

最新文章

  1. 想学图像分割,强烈建议从这5篇图像分割算法综述
  2. matlib 7 在Win10上运行 runtime error
  3. Android -- 带你从源码角度领悟Dagger2入门到放弃(一)
  4. Hibernate type 与java 和 数据库类型对应
  5. 计算机专业自然辩证法期末论文,清华大学自然辩证法-期末论文.docx
  6. python求散点曲线下方面积
  7. 异常处理:try-catch-finally与throws的区别及使用情况
  8. 唯美动态个人404错误页面html源码
  9. Java和U3D比较,Unity热更方案 ILRuntime 和 toLua的比较
  10. 电脑wifi热点软件_手机WiFi信号太差怎么办?掌握这些方法,轻松解决这个问题...
  11. linux basename学习
  12. node重命名文件名_node文件批量重命名
  13. Tomcat CVE-2020-1938(CNVD-2020-10487) 漏洞复现
  14. Unity - Timeline 之 Timeline window(Timeline窗口)
  15. 深入理解 Laravel Eloquent(一)——基本概念及用法
  16. 第二届邯郸钢铁展洽会 | 图扑软件荣获“2022钢铁行业智造之星奖”
  17. Android 集成环信IM,实现头像和昵称的显示
  18. 如何用python画散点图矩阵_Python的散点图竟然能画这么好看
  19. 计算机上如何保存ico格式,怎么把图片转换成ico格式,又快又好
  20. vue3中使用webcamjs拍照

热门文章

  1. 电影媒体行业内容存储库制作渲染文件存储设备解决方案
  2. 比较流行的颜色(16进制表)
  3. 用Python 写一个机器人陪你聊天(文尾有彩蛋)
  4. Python Imaging Library---PIT
  5. 利用GPT2生成莎士比亚写作风格的文本(python实现)
  6. C语言中常犯的错误(一)
  7. 注意力机制 - 注意力提示
  8. 生鲜超市管理系统(JavaSSH)
  9. 翻译:Vulkan VK_EXT_extended_dynamic_state 介绍
  10. 连明工业机器人_十大工业机器人品牌