Elasticsearch学习总结

文章目录

    • 1.ES入门
      • 1.1 环境准备
      • 1.2 倒排索引
      • 1.3 索引的创建&查询&删除
      • 1.4 文档操作
      • 1.5 JavaAPI操作—索引
      • 1.6 JavaAPI操作—文档
    • 2.ES环境
    • 3.ES进阶
    • 4.ES集成
    • 5.ES优化

ES 是一个 开源的高扩展的分布式全文搜索引擎

工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程

1.ES入门

1.1 环境准备

Elasticsearch 的目录结构如下 :

目录 含义
bin 可执行脚本目录
config 配置目录
jdk 内置 JDK 目录
lib 类库
logs 日志目录
modules 模块目录
plugins 插件目录

解压后,进入 bin 文件目录,点击 elasticsearch.bat 文件启动 ES 服务

注意: 9300 端口为 Elasticsearch 集群间组件的通信端口, 9200 端口为浏览器访问的 http协议 RESTful 端口

查看ES是否启动成功:http://localhost:9200/

ES请求遵守REST原则,返回的格式为JSON

1.2 倒排索引

索引是为了优化查询而产生的!

正排索引/正向索引(传统)

id content
1001 my name is zhang san
1002 my name is li si

倒排索引

keyword id
name 1001, 1002
zhang 1001

elasticsearch是一个面向文档的数据库,一条数据在这里就是一个文档

由于ES索引的特点,Type的概念逐渐被弱化

1.3 索引的创建&查询&删除

创建索引:

对比关系型数据库,创建索引就等同于创建数据库

在 Postman 中,向 ES 服务器发 PUT 请求 : http://127.0.0.1:9200/shopping

查询索引:GET请求

①查询所有索引:http://127.0.0.1:9200/_cat/indices?v

health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   shopping J0WlEhh4R7aDrfIc3AkwWQ   1   1          0            0       208b           208b

②查询单个索引:http://127.0.0.1:9200/shopping

表头 含义
health 当前服务器健康状态: green(集群完整) yellow(单点正常、集群不完整) red(单点不正常)
status 索引打开、关闭状态
index 索引名
uuid 索引统一编号
pri 主分片数量
rep 副本数量
docs.count 可用文档数量
docs.deleted 文档删除状态(逻辑删除)
store.size 主分片和副分片整体占空间大小
pri.store.size 主分片占空间大小

删除索引:DELETE请求 http://127.0.0.1:9200/shopping

1.4 文档操作

ES中的文档对应于关系数据库中的表数据

创建文档:

POST 请求 : http://127.0.0.1:9200/shopping/_doc,请求体JSON内容为:

{
    "title":"小米手机",
    "category":"小米",
    "images":"http://www.gulixueyuan.com/xm.jpg",
    "price":3999.00
}

由于没有指定数据唯一性标识(ID),默认情况下, ES 服务器会随机生成一个

注意:此处发送请求的方式必须为 POST,不能是 PUT,否则会发生错误

如果想要自定义唯一性标识,需要在创建时指定: http://127.0.0.1:9200/shopping/_doc/1001

1001就为数据的主键,即唯一标识

注意:如果增加数据时明确数据主键,那么请求方式也可以为 PUT

主键查询:GET 请求 : http://127.0.0.1:9200/shopping/_doc/1001

查看索引下所有数据: GET 请求 : http://127.0.0.1:9200/shopping/_search

全局修改:

和新增文档一样,输入相同的 URL 地址请求,如果请求体变化,会将原有的数据内容覆盖

POST 请求 : http://127.0.0.1:9200/shopping/_doc/1001

局部修改:

POST 请求 : http://127.0.0.1:9200/shopping/_update/1001

请求体JSON内容为:

{
	"doc": {
		"title":"小米手机",
		"category":"小米"
	}
}

删除:

删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)

DELETE 请求 : http://127.0.0.1:9200/shopping/_doc/1001

条件查询:

①URL带参查询

查找category为小米的文档,GET请求 : http://127.0.0.1:9200/shopping/_search?q=category:小米

②请求体带参查询

接下带JSON请求体,还是查找category为小米的文档,GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:

{
	"query":{
		"match":{
			"category":"小米"
		}
	}
}

③带请求体方式的查找所有内容

{
	"query":{
		"match_all":{}
	}
}

④查询指定字段

{
	"query":{
		"match_all":{}
	},
	"_source":["title"]
}

分页查询:

计算公式:from =(页码-1)*每页数据条数

{
	"query":{
		"match_all":{}
	},
	"from":0,
	"size":2
}

查询排序:

如果你想通过排序查出价格最高的手机,GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:

{
	"query":{
		"match_all":{}
	},
	"sort":{
		"price":{
			"order":"desc"
		}
	}
}

多条件查询:

假设想找出小米牌子,价格为3999元的。(must相当于数据库的&&)

GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:

{
    "query":{
        "bool":{
            "must":[
                {
                    "match":{
                        "category":"小米"
                    }
                },
                {
                    "match":{
                        "price":3999
                    }
                }
            ]
        }
    }
}

假设想找出小米和华为的牌子 (should相当于数据库的||)

{
    "query":{
        "bool":{
            "should":[
                {
                    "match":{
                        "category":"小米"
                    }
                },
                {
                    "match":{
                        "category":"华为"
                    }
                }
            ]
        }
    }
}

范围查询:

假设想找出小米和华为的牌子,价格大于3000元的手机。

GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:

{
    "query":{
        "bool":{
            "should":[
                {
                    "match":{
                        "category":"小米"
                    }
                },
                {
                    "match":{
                        "category":"华为"
                    }
                }
            ],
            "filter":{
                "range":{
                    "price":{
                        "gt":3000
                    }
                }
            }
        }
    }
}

全文检索:

功能像搜索引擎那样,如品牌输入“小华”,返回结果带回品牌有“小米”和华为的。

GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:

{
	"query":{
		"match":{
			"category" : "小华"
		}
	}
}

完全匹配:

{
    "query":{
        "match_phrase":{
            "category":"红米"
        }
    }
}

高亮查询:

以category字段高亮显示为例:

{
    "query":{
        "match_phrase":{
            "category":"红米"
        }
    },
    "highlight":{
        "fields":{
            "category":{}
        }
    }
}

聚合查询:

聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很多其他的聚合,例如取最大值max、平均值avg等等。

接下来按price字段进行分组:

GET请求 : http://127.0.0.1:9200/shopping/_search,附带JSON体如下:

{
    "aggs":{ //聚合操作
        "price_group":{ //名称,随意起
            "terms":{ //分组
                "field":"price" //分组字段
            }
        }
    },
    "size":0//表示不用显示原始数据
}

若想对所有手机价格求平均值

{
    "aggs":{ //聚合操作
        "price_avg":{ //名称,随意起
            "avg":{ //分组
                "field":"price" //分组字段
            }
        }
    },
    "size":0//表示不用显示原始数据
}

映射关系:

有了索引库,等于有了数据库中的 database

接下来就需要建索引库(index)中的映射了,类似于数据库(database)中的表结构(table)

创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)

①先创建一个索引:

# PUT http://127.0.0.1:9200/user

②创建映射

# PUT http://127.0.0.1:9200/user/_mapping
{
    "properties":{
        "name":{
            "type":"text",//可分词
            "index":true //可索引
        },
        "sex":{
            "type":"keyword",//不可分词,完全匹配
            "index":true
        },
        "tel":{
            "type":"keyword",
            "index":false//不可索引
        }
        
    }
}

③查询映射

#GET http://127.0.0.1:9200/user/_mapping

1.5 JavaAPI操作—索引

环境准备:

添加依赖

<dependencies>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>7.8.0</version>
    </dependency>
    <!-- elasticsearch 的客户端 -->
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.8.0</version>
    </dependency>
    <!-- elasticsearch 依赖 2.x 的 log4j -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.9</version>
    </dependency>
    <!-- junit 单元测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

1.索引创建:

public class Es_Index_Create {
    public static void main(String[] args) throws IOException {
        //创建ES客户端
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http"))
        );
//        System.out.println(client);
        //创建索引
        CreateIndexRequest request = new CreateIndexRequest("student");
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        //响应状态
        boolean acknowledged = response.isAcknowledged();
        System.out.println("索引操作:" + acknowledged);
        //关闭ES客户端
        client.close();
    }
}

2.查询索引:

public class Es_Index_Search {
    public static void main(String[] args) throws IOException {
        ...
        //查询索引
        GetIndexRequest request = new GetIndexRequest("student");

        GetIndexResponse getIndexResponse = client.indices().get(request, RequestOptions.DEFAULT);
        System.out.println(getIndexResponse.getSettings());
        //关闭ES客户端
        client.close();
    }
}

3.删除索引:

public class Es_Index_Delete {
    public static void main(String[] args) throws IOException {
        ...
        //删除索引
        DeleteIndexRequest request = new DeleteIndexRequest("student");

        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        System.out.println("删除结果:" + delete.isAcknowledged());
        //关闭ES客户端
        client.close();
    }
}

1.6 JavaAPI操作—文档

1.创建文档:

public class Es_Doc_Insert {
    public static void main(String[] args) throws IOException {
        //创建ES客户端
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http"))
        );
        //插入数据
        IndexRequest indexRequest = new IndexRequest();
        indexRequest.index("user").id("1001");

        User user = new User("zhangsan", "男", 23);

        //向ES插入数据,必须将数据转化为json格式
        ObjectMapper mapper = new ObjectMapper();
        String userJson = mapper.writeValueAsString(user);
        indexRequest.source(userJson, XContentType.JSON);
        IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println(response.getResult());

        //关闭ES客户端
        client.close();
    }
}

2.修改文档:

public class Es_Doc_Update {
    public static void main(String[] args) throws IOException {
        ...
        //更新数据
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index("user").id("1001");
        updateRequest.doc(XContentType.JSON,"sex","女");

        UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(updateResponse.getResult());

        //关闭ES客户端
        client.close();
    }
}

3.查询文档:

public class Es_Doc_Get {
    public static void main(String[] args) throws IOException {
        ...
        //查询数据
        GetRequest getRequest = new GetRequest();
        getRequest.index("user").id("1001");
        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);

        System.out.println(response.getSourceAsString());
        //关闭ES客户端
        client.close();
    }
}

4.删除文档:

DeleteRequest request = new DeleteRequest().index("user").id("1001");
//客户端发送请求,获取响应对象
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);

5.批量新增:

//批量插入数据
BulkRequest bulkRequest = new BulkRequest();

bulkRequest.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON,"name","lisi"));
bulkRequest.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON,"name","wanger"));
bulkRequest.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON,"name","lihua"));

BulkResponse response = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println("花费时间:"+response.getTook());

6.批量删除:

//创建批量删除请求对象
BulkRequest request = new BulkRequest();
request.add(new DeleteRequest().index("user").id("1001"));
request.add(new DeleteRequest().index("user").id("1002"));
request.add(new DeleteRequest().index("user").id("1003"));
//客户端发送请求,获取响应对象
BulkResponse responses = client.bulk(request, RequestOptions.DEFAULT);
//打印结果信息
System.out.println("took:" + responses.getTook());
System.out.println("items:" + responses.getItems());

7.全量查询:查询所有数据

//查询索引中全部的数据
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());

8.条件查询:

//条件查询:termQuery
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
searchRequest.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age",23)));
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
for (SearchHit hit:hits){
System.out.println(hit.getSourceAsString());
}

9.分页查询:

SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
builder.from(0);
builder.size(2);
searchRequest.source(builder);

SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
for (SearchHit hit:hits){
System.out.println(hit.getSourceAsString());
}

10.查询排序:

//查询排序
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
builder.sort("age", SortOrder.ASC);
searchRequest.source(builder);

SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();

11.过滤字段:

//过滤字段
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
String[] include = {"name"};
String[] exclude = {};
builder.fetchSource(include, exclude);
searchRequest.source(builder);

SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());

12.组合查询:

//组合查询
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder builder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        boolQueryBuilder.must(QueryBuilders.matchQuery("age",23));
boolQueryBuilder.mustNot(QueryBuilders.matchQuery("sex","男"));
boolQueryBuilder.should(QueryBuilders.matchQuery("age",23));
boolQueryBuilder.should(QueryBuilders.matchQuery("age",24));

builder.query(boolQueryBuilder);
searchRequest.source(builder);

SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());

13.范围查询:

//范围查询
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder builder = new SearchSourceBuilder();
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
rangeQuery.gte(20);
rangeQuery.lte(40);

builder.query(rangeQuery);
searchRequest.source(builder);

SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());

14.模糊查询:

SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder builder = new SearchSourceBuilder();

builder.query(QueryBuilders.fuzzyQuery("name","lisi").fuzziness(Fuzziness.AUTO));
searchRequest.source(builder);

SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
for (SearchHit hit:hits){
System.out.println(hit.getSourceAsString());
}

15.高亮查询:

// 高亮查询
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();

16.聚合查询:

SearchSourceBuilder builder = new SearchSourceBuilder();

MaxAggregationBuilder maxAggregationBuilder = AggregationBuilders.max("maxAge").field("age");
builder.aggregation(maxAggregationBuilder);

searchRequest.source(builder);

17.分组查询:

SearchRequest request = new SearchRequest().indices("user");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.aggregation(AggregationBuilders.terms("age_groupby").field("age"));
//设置请求体
request.source(sourceBuilder);
//3.客户端发送请求,获取响应对象
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.打印响应结果
SearchHits hits = response.getHits();

2.ES环境

3.ES进阶

4.ES集成

5.ES优化

你可能感兴趣的:(Java开发,elasticsearch)