简介
The Elastic Stack, 包括 Elasticsearch、 Kibana、 Beats 和 Logstash(也称为 ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。
Elaticsearch,简称为 ES, ES 是一个开源的高扩展的分布式全文搜索引擎, 是整个 ElasticStack 技术栈的核心。
它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理 PB 级别的数据。
入门
官方网址
官方文档
Elasticsearch 7.8.0下载页面
启动
测试工具
如果直接通过浏览器向 Elasticsearch 服务器发请求,那么需要在发送的请求中包含 HTTP 标准的方法,而 HTTP 的大部分特性且仅支持 GET 和 POST 方法。所以为了能方便地进行客户端的访问,可以使用 Postman 软件Postman 是一款强大的网页调试工具,提供功能强大的 Web API 和 HTTP 请求调试。
软件功能强大,界面简洁明晰、操作方便快捷,设计得很人性化。 Postman 中文版能够发送任何类型的 HTTP 请求 (GET, HEAD, POST, PUT…),不仅能够表单提交,且可以附带任意类型请求体。
Postman下载页面
与传统的mysql的区别
底层原理:倒排索引
正排索引
在建立索引的时候结构比较简单,建立比较方便且易于维护;因为索引是基于文档建立的,若是有新的文档加入,直接为该文档建立一个新的索引块,挂接在原来索引文件的后面。若是有文档删除,则直接找到该文档号文档对应的索引信息,将其直接删除。 他适合根据文档ID来查询对应的内容。但是在查询一个keyword在哪些文档里包含的时候需对所有的文档进行扫描以确保没有遗漏,这样就使得检索时间大大延长,检索效率低下。 比如有几个文档及里面的内容,他正排索引构建的结果如下图:
倒排索引:基于正排索引,将每个文档的内容通过关键字进行排序(去掉出现频率较高的无用字,比如的,是这种,剩下的就是关键字),查询时通过倒排索引可以查询到该关键词出现的文档位置是在1和3中;然后再通过正排索引查询到文档1和3的内容并返回结果。
倒排索引主要由单词词典(Term Dictionary)和倒排列表(Posting List)及倒排文件(Inverted File)组成。
单词词典(Term Dictionary):搜索引擎的通常索引单位是单词,单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向“倒排列表”的指针。 倒排列表(PostingList):倒排列表记载了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息及频率(作关联性算分),每条记录称为一个倒排项(Posting)。根据倒排列表,即可获知哪些文档包含某个单词。 倒排文件(Inverted File):所有单词的倒排列表往往顺序地存储在磁盘的某个文件里,这个文件即被称之为倒排文件,倒排文件是存储倒排索引的物理文件。
2、基本使用
1、HTTP-索引-创建
创建相同的数据库会进行报错
2、**HTTP-索引-查询 & 删除**
查看所有索引 在 Postman 中,向 ES 服务器发 GET 请求 : http://127.0.0.1:9200/_cat/indices?v
这里请求路径中的_cat 表示查看的意思, indices 表示索引,所以整体含义就是查看当前 ES服务器中的所有索引,就好像 MySQL 中的 show tables 的感觉,服务器响应结果如下 :
具体参数如下:
查询单个索引:
删除索引:
文档的创建(需要有索引):
在shopping的索引下创建了一个_doc的文档,文档的内容为图中所示
返回结果如下:
自定义唯一标识:
3、HTTP-查询-主键查询 & 全查询
1、查看文档时,需要指明文档的唯一性标识,类似于 MySQL 中数据的主键查询
在 Postman 中,向 ES 服务器发 GET 请求 : http://127.0.0.1:9200/shopping/_doc/1
返回结果如下:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version": 1,
"_seq_no": 1,
"_primary_term": 1,
"found": true,
"_source": {
"title": "小米手机",
"category": "小米",
"images": "[http://www.gulixueyuan.com/xm.jpg](http://www.gulixueyuan.com/xm.jpg)",
"price": 3999
}
}
2、查找不存在的内容,向 ES 服务器发 GET 请求 : http://127.0.0.1:9200/shopping/_doc/1001
返回结果如下:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1001",
"found": false
}
3、查看索引下所有数据,向 ES 服务器发 GET 请求 : http://127.0.0.1:9200/shopping/_search
返回结果如下:
{
"took": 133,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "shopping",
"_type": "_doc",
"_id": "ANQqsHgBaKNfVnMbhZYU",
"_score": 1,
"_source": {
"title": "小米手机",
"category": "小米",
"images": "[http://www.gulixueyuan.com/xm.jpg](http://www.gulixueyuan.com/xm.jpg)",
"price": 3999
}
},
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_score": 1,
"_source": {
"title": "小米手机",
"category": "小米",
"images": "[http://www.gulixueyuan.com/xm.jpg](http://www.gulixueyuan.com/xm.jpg)",
"price": 3999
}
}
]
}
}
4、HTTP-全量修改 & 局部修改 & 删除
全量修改 和新增文档一样,输入相同的 URL 地址请求,如果请求体变化,会将原有的数据内容覆盖
在 Postman 中,向 ES 服务器发 POST 请求 : http://127.0.0.1:9200/shopping/_doc/1
请求体JSON内容为:
{
"title":"华为手机",
"category":"华为",
"images":"http://www.gulixueyuan.com/hw.jpg",
"price":1999.00
}
修改成功后,服务器响应结果:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version": 2,
"result": "updated",//<-----------updated 表示数据被更新
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 1
}
局部修改 修改数据时,也可以只修改某一给条数据的局部信息
在 Postman 中,向 ES 服务器发 POST 请求 : http://127.0.0.1:9200/shopping/_update/1
请求体JSON内容为:
{
"doc": {
"title":"小米手机",
"category":"小米"
}
}
返回结果如下:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version": 3,
"result": "updated",//<-----------updated 表示数据被更新
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}
在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_doc/1,查看修改内容:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version": 3,
"_seq_no": 3,
"_primary_term": 1,
"found": true,
"_source": {
"title": "小米手机",
"category": "小米",
"images": "[http://www.gulixueyuan.com/hw.jpg](http://www.gulixueyuan.com/hw.jpg)",
"price": 1999
}
}
删除 删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)。
在 Postman 中,向 ES 服务器发 DELETE 请求 : http://127.0.0.1:9200/shopping/_doc/1
返回结果:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version": 4,
"result": "deleted",//<---删除成功
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 4,
"_primary_term": 1
}
在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_doc/1,查看是否删除成功:
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"found": false
}
5、HTTP-条件查询 & 分页查询 & 查询排序
URL带参查询 查找category为小米的文档,在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search?q=category:小米
URL带参数形式查询,这很容易让不善者心怀恶意,或者参数值出现中文会出现乱码情况。为了避免这些情况,我们可用使用带JSON请求体请求进行查询。
带请求体方式的查找所有内容 查找所有文档内容,也可以这样,在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下
查询指定字段 如果你想查询指定字段,在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
分页查询 在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
查询排序 如果你想通过排序查出价格最高的手机,在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
6、HTTP-多条件查询 & 范围查询
多条件查询 假设想找出小米牌子,价格为3999元的。(must相当于数据库的&&)
在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
假设想找出小米和华为的牌子。(should相当于数据库的||)
在 Postman 中,向 ES 服务器发 GET请求(我的数据里面是没有的所以报错了) : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
范围查询 假设想找出小米和华为的牌子,价格大于2000元的手机。
在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
{
"query":{
"bool":{
"should":[{
"match":{
"category":"小米"
}
},{
"match":{
"category":"华为"
}
}],
"filter":{
"range":{
"price":{
"gt":2000
}
}
}
}
}
}
7、HTTP-全文检索 & 完全匹配 & 高亮查询
全文检索 这功能像搜索引擎那样,如品牌输入“小华”,返回结果带回品牌有“小米”和华为的。
在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
完全匹配 在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
高亮查询 在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
8、HTTP-聚合查询
聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很多其他的聚合,例如取最大值max、平均值avg等等。
接下来按price字段进行分组:
在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
上面返回结果会附带原始数据的。若不想要不附带原始数据的结果,在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
若想对所有手机价格求平均值。
在 Postman 中,向 ES 服务器发 GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:
9、HTTP-映射关系
有了索引库,等于有了数据库中的 database。
接下来就需要建索引库(index)中的映射了,类似于数据库(database)中的表结构(table)。
创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)。
先创建索引:
创建映射
查询user下的映射
增加其他的映射关系
查找name含有”小“数据:
查找sex含有”男“数据:
找不想要的结果,只因创建映射时"sex"的类型为"keyword"。
"sex"只能完全为”男的“,才能得出原数据。
查询电话(报错只因创建映射时"tel"的"index"为false。)
3、JavaAPI-Idea环境准备
新建Maven工程。
1、添加依赖
org.elasticsearch elasticsearch7.8.0 org.elasticsearch.client elasticsearch-rest-high-level-client7.8.0 org.apache.logging.log4j log4j-api2.8.2 org.apache.logging.log4j log4j-core2.8.2 com.fasterxml.jackson.core jackson-databind2.9.9 junit junit4.12
** 2、创建一个客户端对象:**
import java.io.IOException;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
public class HelloElasticsearch {
public static void main(String[] args) throws IOException {
// 创建客户端对象
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
// ...
System.out.println(client);
// 关闭客户端连接
client.close();
}
}
** 3、JavaAPI-索引-创建**
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import java.io.IOException;
public class CreateIndex {
public static void main(String[] args) throws IOException {
// 创建客户端对象
RestHighLevelClient client =
new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")));
// 创建索引 - 请求对象
CreateIndexRequest request =
new CreateIndexRequest("user2");
// 发送请求,获取响应
CreateIndexResponse response =
client.indices().create(request,
RequestOptions.DEFAULT);
boolean acknowledged = response.isAcknowledged();
// 响应状态
System.out.println("操作状态 = " + acknowledged);
// 关闭客户端连接
client.close();
}
}
运行结果:操作状态 = true
1、JavaAPI-索引-查询 & 删除
**1、查询**
** 2、删除**
2、JavaAPI-文档-新增 & 修改
频繁的连接ES和关闭所以进行代码重构,使用时可以直接调用
1、创建ES接口
import org.elasticsearch.client.RestHighLevelClient;
public interface ElasticsearchTask {
void doSomething(RestHighLevelClient client) throws Exception;
}
2、创建静态方法
public class ConnectElasticsearch{
public static void connect(ElasticsearchTask task){
// 创建客户端对象
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
try {
task.doSomething(client);
// 关闭客户端连接
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
新增:
修改:
这里会有一个bug错误信息如下(这是因为pom文件涵盖了log4j2但是没有对应的文件,可以在resources配置log4j2.xml文件):
运行调试代码的时候报的一个错,报错如下: ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property ‘log4j2.debug’ to show Log4j2 internal initialization logging.
log4j2文件模板如下:
%d{MM-dd-yyyy} %p %c{1.} [%t] -%M-%L- %m%n
3、JavaAPI-文档-查询 & 删除
查询
删除
4、JavaAPI-文档-批量新增 & 批量删除
批量新增
批量删除
5、JavaAPI-文档-高级查询-全量查询
全量查询
6、JavaAPI-文档-高级查询-分页查询 & 条件查询 & 查询排序
条件查询
**结果:**
分页查询:
** 结果:**
排序查询:
结果:
7、JavaAPI-文档-高级查询-模糊查询 & 高亮查询
模糊查询
结果:
高亮查询:
package tetsfile;
import org.elasticsearch.action.search.*;
import org.elasticsearch.client.*;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.*;
import org.elasticsearch.search.builder.*;
import org.elasticsearch.search.fetch.subphase.highlight.*;
import java.util.*;
public class QueryDoc5 {
public static final ElasticsearchTask SEARCH_WITH_HIGHLIGHT = client -> {
// 高亮查询
SearchRequest request = new SearchRequest().indices("user");
//2.创建查询请求体构建器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//构建查询方式:高亮查询
TermsQueryBuilder termsQueryBuilder =
QueryBuilders.termsQuery("name","zhangsan");
//设置查询方式
sourceBuilder.query(termsQueryBuilder);
//构建高亮字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("");//设置标签前缀
highlightBuilder.postTags("");//设置标签后缀
highlightBuilder.field("name");//设置高亮字段
//设置高亮构建对象
sourceBuilder.highlighter(highlightBuilder);
//设置请求体
request.source(sourceBuilder);
//3.客户端发送请求,获取响应对象
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.打印响应结果
SearchHits hits = response.getHits();
System.out.println("took::"+response.getTook());
System.out.println("time_out::"+response.isTimedOut());
System.out.println("total::"+hits.getTotalHits());
System.out.println("max_score::"+hits.getMaxScore());
for (SearchHit hit : hits) {
String sourceAsString = hit.getSourceAsString();
System.out.println(sourceAsString);
//打印高亮结果
Map highlightFields = hit.getHighlightFields();
System.out.println(highlightFields);
}
};
public static void main(String[] args) {
ConnectElasticsearch.connect(SEARCH_WITH_HIGHLIGHT);
}
}
** 结果:**
8、JavaAPI-文档-高级查询-最大值查询 & 分组查询
最大值查询
分组查询:



