【elasticsearch】1.入门基本操作
ES入门操作 HTTP
安装ES
ElasticSearch官网下载,以最新版为例,elasticsearch-7.17.0-windows-x86_64.zip
将压缩包解压,进入elasticsearch中的bin目录,双击elasticsearch.bat运行,在浏览器中输入http://localhost:9200,按下回车,出现以下信息说明elasticsearch启动成功
索引操作(创建、查询、删除)
创建索引
PUT:http://127.0.0.1:9200/shopping
注意:索引创建不能用POST请求
查询索引
1. 查询指定名称的索引
GET:http://127.0.0.1:9200/shopping
2. 查询全部索引
GET:http://127.0.0.1:9200/_cat/indices?v
删除索引
DELETE :http://127.0.0.1:9200/shopping
文档操作(创建、查询、修改、删除)
创建文档 /_doc或者/_create
1. 指定id时,POST和PUT请求等效,即幂等性
POST:http://127.0.0.1:9200/shopping/_doc/1001
2. 不指定id,只能用POST请求
POST:http://127.0.0.1:9200/shopping/_doc
{
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com.xm.jpg",
"price":3999.0
}
查询文档 /_search
1. 查询指定id的文档
GET:http://127.0.0.1:9200/shopping/_doc/1001
2. 查询索引下所有的文档
GET:http://127.0.0.1:9200/shopping/_search
修改文档
1. 全量修改 PUT & POST(幂等性)/_doc
POST:http://127.0.0.1:9200/shopping/_doc/1001
参数为新的json数据
{
"title":"华为手机",
"category":"华为",
"images":"http://www.gulixueyuan.com.hw.jpg",
"price":5999.0
}
2. 局部修改 POST /_update
POST:http://127.0.0.1:9200/shopping/_update/1001
注意: 将请求路径中的_doc修改为_update。_doc表示新增,等价于_create
参数也有变化:
{
"doc":{
"title":"魅族手机"
}
}
删除文档
DELETE:http://127.0.0.1:9200/shopping/_doc/1001
高级查询(条件、分页、排序)
1. ?拼接查询条件
语法格式:_search?q=
查询小米品牌的手机
GET:http://127.0.0.1:9200/shopping/_search?q=category:小米
2. body传递查询条件
POST:http://127.0.0.1:9200/shopping/_search
{
"query":{
"match":{
"category":"小米"
}
}
}
- query 表示查询条件
- match 表示匹配查询
- match_all 查询全部
{
"query":{
"match_all":{
}
}
}
3. 分页查询
{
"query":{
"match_all":{
}
},
"from":0,
"size":3
}
- from:表示当前页数据的起始位置 计算公式:(页码-1)*size
- size:表示每页的数据条数
4. 查询结果过滤显示
查询结果只显示title字段
{
"query":{
"match_all":{
}
},
"from":0,
"size":3,
"_source":["title"]
}
- _source:查询结果过滤,数组格式,表示想要显示的字段
5. 查询结果排序
对查询结果进行排序,按照价格降序排列
{
"query":{
"match_all":{
}
},
"from":0,
"size":3,
"_source":["title"],
"sort":{
"price":{
"order": "desc"
}
}
}
- sort:表示对查询结果进行排序
- order:表示排序方式 asc:升序,desc:降序
多条件查询、范围查询
- bool: 表示多条件参数
- must:数组格式,表示多条件同时满足;should:表示至少有一个满足
查询2999元的小米手机
{
"query":{
"bool":{
"must":[
{
"match":{
"category":"小米"
}
},
{
"match":{
"price":2999
}
}
]
}
}
}
查询小米或者华为品牌的手机
{
"query":{
"bool":{
"should":[
{
"match":{
"category":"小米"
}
},
{
"match":{
"category":"华为"
}
}
]
}
}
}
查询价格在2000-3000范围内的小米或者华为手机
{
"query":{
"bool":{
"should":[
{
"match":{
"category":"小米"
}
},
{
"match":{
"category":"华为"
}
}
],
"filter":{
"range":{
"price":{
"gt" : 2000,
"lt" : 3000
}
}
}
}
}
}
- filter:表示过滤
- range:表示范围
- gt:表示大于
- gte:表示大于等于
- lt:表示小于
全文检索、高亮显示
ES在存储或者查询时,会进行分词处理。使用match进行匹配时,查询结果为分词后的查询结果。例如:
{
"query":{
"match":{
"category":"小华"
}
}
}
上述代码的查询结果中包含所有"小"或者"华"的数据,对查询条件进行了分词。
如果不想对查询条件进行分词,使用match_phrase
{
"query":{
"match_phrase":{
"category":"小华"
}
}
}
- match_phrase:表示不对查询条件进行分词
检索结果高亮显示
查询小米品牌的手机,并进行高亮显示
{
"query":{
"match_phrase":{
"category":"小米"
}
},
"highlight":{
"fields":{
"category":{}
}
}
}
- highlight:高亮显示
- fields:高亮显示的字段
聚合操作
1. 语法
"aggregations" : {
"<aggregation_name>" : { <!--聚合的名字 -->
"<aggregation_type>" : { <!--聚合的类型 -->
<aggregation_body> <!--聚合体:对哪些字段进行聚合 -->
}
[,"meta" : { [<meta_data_body>] } ]? <!--元 -->
[,"aggregations" : { [<sub_aggregation>]+ } ]? <!--在聚合里面在定义子聚合 -->
}
}
2. 聚合的类型
- sum:求和
- max:最大值
- min:最小值
- avg:平均值
- terms:分组并计数
- cardinality:去重计数
- stats:统计,会直接显示多种聚合结果,总记录数,最大值,最小值,平均值,汇总(求和)值
- percentiles:百分比,对指定字段的值按从小到大累计每个值对应的文档数的占比,返回指定占比比例对应的值
3. 示例
对不同价格的手机进行分组
{
"aggs":{ // 聚合操作
"price_group":{ // 名称,随意命名
"terms":{ // 分组
"field":"price" // 分组字段
}
}
},
"size":0
}
- “size”:0,表示不附带原始数据,只显示聚合结果
求所有手机价格的平均值
{
"aggs":{ // 聚合操作
"price_avg":{ // 名称,随意命名
"avg":{ // 平均值
"field":"price" // 求平均值的字段
}
}
},
"size":0
}
对价格进行统计
{
"aggs":{
"price_stats":{
"stats":{
"field":"price"
}
}
},
"size":0
}
多值查询-最大最小值和平均值
{
"aggs":{
"price_max":{
"max":{
"field":"price"
}
},
"price_min":{
"min":{
"field":"price"
}
},
"price_avg":{
"avg":{
"field":"price"
}
}
},
"size":0
}
分组后聚合,根据性别分组求平均工资
{
"aggs":{
"category":{
"terms":{
"field":"sex"
},
"aggs":{
"salary_avg":{
"avg":{
"field":"salary"
}
}
}
}
},
"size":0
}
注意:ES不能对字符串类型字段进行聚合操作
映射关系 _mapping
创建user索引
GET:http://127.0.0.1:9200/user
给user添加映射关系
PUT:http://127.0.0.1:9200/user/_mapping
{
"properties" : { //定义属性
"name" : {
"type" : "text", //字段类型 text表示可分词
"index" : true //字段是否可以被索引查询
},
"sex" : {
"type" : "keyword", //字段类型 keyword表示不可分词
"index" : true
},
"phone" : {
"type" : "keyword", //字段类型 keyword表示不可分词
"index" : false
}
}
}
查询user的映射关系
GET:http://127.0.0.1:9200/user/_mapping
定义好映射关系后,可进行对user的match匹配检索,具体检索方法此处省略。
ES入门操作 Java API
环境准备
maven依赖
<!--elasticsearch-->
<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>
<!--解决客户端版本不一致导致创建索引时报错的问题-->
<exclusions>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.8.0</version>
</dependency>
<!--jackson-databind-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
创建es客户端
public class ESDemo_Client {
public static void main(String[] args) throws IOException {
// 1.创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost",9200,"http"))
);
// 关闭ES客户端
esClient.close();
}
}
索引操作(创建、查询、删除)
创建索引
// 2.索引操作 创建索引
CreateIndexRequest request = new CreateIndexRequest("user");
CreateIndexResponse createIndexResponse =
esClient.indices().create(request, RequestOptions.DEFAULT);
// 响应状态
boolean acknowledged = createIndexResponse.isAcknowledged();
System.out.println("创建索引:" + acknowledged);
查询索引
// 3.索引操作 查询索引
GetIndexRequest request = new GetIndexRequest("user");
GetIndexResponse getIndexResponse =
esClient.indices().get(request, RequestOptions.DEFAULT);
// 响应信息
System.out.println("getAliases() = " + getIndexResponse.getAliases());
System.out.println("getMappings() = " + getIndexResponse.getMappings());
System.out.println("getSettings() = " + getIndexResponse.getSettings());
删除索引
// 4.索引操作 删除索引
DeleteIndexRequest request = new DeleteIndexRequest("user");
AcknowledgedResponse deleteResponse =
esClient.indices().delete(request, RequestOptions.DEFAULT);
// 响应状态
boolean acknowledged = deleteResponse.isAcknowledged();
System.out.println("删除索引:" + acknowledged);
文档操作(创建、修改、查询、删除)
创建文档
ic class ESDemo_Doc {
public static void main(String[] args) throws IOException {
// 1.创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
// 2.文档操作 创建文档
IndexRequest request = new IndexRequest();
// 指定索引和id
request.index("user").id("1001");
// 准备数据
User user = new User();
user.setName("zhangsan");
user.setSex("男");
user.setAge(30);
// 向ES插入数据,必须将数据转换为JSON格式
ObjectMapper mapper = new ObjectMapper();
String userJson = mapper.writeValueAsString(user);
request.source(userJson, XContentType.JSON);
// 创建文档
IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
System.out.println("response = " + response.getResult());
// 关闭ES客户端
esClient.close();
}
修改文档
// 3.文档操作 修改文档
UpdateRequest request = new UpdateRequest();
// 指定索引和id
request.index("user").id("1001");
// 修改数据
request.doc(XContentType.JSON, "sex", "女");
// 修改文档
UpdateResponse response = esClient.update(request, RequestOptions.DEFAULT);
System.out.println("response = " + response.getResult());
查询文档
// 4.查询数据
GetRequest request = new GetRequest();
// 指定查询的 索引和id
request.index("user").id("1001");
GetResponse response = esClient.get(request, RequestOptions.DEFAULT);
// 结果输出
System.out.println(response.getSourceAsString());
删除文档
// 5.删除文档
DeleteRequest request = new DeleteRequest();
// 指定要删除的 索引和id
request.index("user").id("1001");
DeleteResponse response = esClient.delete(request, RequestOptions.DEFAULT);
System.out.println(response.getResult());
文档操作(批量新增、批量删除)
批量新增
public class ESDemo_Doc_Batch {
public static void main(String[] args) throws IOException {
// 1.创建ES客户端
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http"))
);
// 2.文档操作 批量新增
BulkRequest request = new BulkRequest();
// 准备数据
request.add(new IndexRequest("user").id("1001").source(XContentType.JSON,"name","zhangsan"));
request.add(new IndexRequest("user").id("1002").source(XContentType.JSON,"name","lisi"));
request.add(new IndexRequest("user").id("1003").source(XContentType.JSON,"name","wangwu"));
// 批量新增
BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
System.out.println("耗时:" + response.getTook());
System.out.println(Arrays.toString(response.getItems()));
// 关闭ES客户端
esClient.close();
}
}
批量删除
// 3.文档操作 批量删除
BulkRequest request = new BulkRequest();
// 准备数据
request.add(new DeleteRequest("user").id("1001"));
request.add(new DeleteRequest("user").id("1002"));
request.add(new DeleteRequest("user").id("1003"));
// 批量删除
BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
System.out.println("耗时:" + response.getTook());
System.out.println(Arrays.toString(response.getItems()));
文档操作-高级查询(全量、条件、分页、排序、字段过滤)
- SearchRequest:查询请求对象
- SearchSourceBuilder:查询构造器
- QueryBuilder:条件构造器
1. 查询全部数据 QueryBuilders.matchAllQuery()
// 1.查询索引中全部数据
SearchRequest request = new SearchRequest();
request.indices("user");
// 准备查询条件
request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
2. 条件查询 QueryBuilders.termQuery()
// 2.条件查询
SearchRequest request = new SearchRequest();
request.indices("user");
// 准备查询条件
request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age",30)));
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
3. 分页查询 searchSourceBuilder.from() searchSourceBuilder.size()
// 3.分页查询
SearchRequest request = new SearchRequest();
request.indices("user");
// 准备分页信息
SearchSourceBuilder searchBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
searchBuilder.from(0); //当前页的起始位置,(页码-1)*size
searchBuilder.size(2); //每页条数
request.source(searchBuilder);
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
4. 查询结果排序 searchSourceBuilder.sort()
// 4.查询结果排序
SearchRequest request = new SearchRequest();
request.indices("user");
// 查询全部数据
SearchSourceBuilder searchBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
// 查询结果按年龄降序排列
searchBuilder.sort("age", SortOrder.DESC);
request.source(searchBuilder);
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
5. 字段过滤 searchSourceBuilder.fetchSource()
// 5.字段过滤
SearchRequest request = new SearchRequest();
request.indices("user");
// 查询全部数据
SearchSourceBuilder searchBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
// 字段过滤
String[] includes = {"name"}; //需要的字段
String[] excludes = {}; //排除的字段
searchBuilder.fetchSource(includes, excludes);
request.source(searchBuilder);
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
文档操作-高级查询(多条件查询、范围查询)
6. 组合查询 QueryBuilders.boolQuery()
// 6.组合查询
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
// 查询年龄30并且性别为女的用户
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("age", 30));
boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "女"));
searchBuilder.query(boolQueryBuilder);
request.source(searchBuilder);
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
7. 范围查询 QueryBuilders.rangeQuery()
// 7.范围查询
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
// 查询年龄在30~40的用户
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
rangeQuery.gte(30); //大于等于30
rangeQuery.lte(40); //小于等于40
searchBuilder.query(rangeQuery);
request.source(searchBuilder);
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
文档操作-高级查询(全文检索、高亮显示)
8. 全文检索(模糊查询) QueryBuilders.fuzzyQuery()
// 8.全文检索(模糊查询)
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
// 指定模糊查询的内容,以及偏差距离
FuzzyQueryBuilder fuzzyQuery =
QueryBuilders.fuzzyQuery("name", "wangwu").fuzziness(Fuzziness.TWO);
searchBuilder.query(fuzzyQuery);
request.source(searchBuilder);
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
9. 查询结果高亮显示 HighlightBuilder
// 9.查询结果高亮显示
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
// 查询名字为王五的用户,注意,查询中文时,需要使用 属性.keyword
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name.keyword", "王五");
// 高亮显示设置
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("name"); //高亮字段
highlightBuilder.preTags("<font color='red'>"); //前缀标签
highlightBuilder.postTags("</font>"); //后缀标签
searchBuilder.highlighter(highlightBuilder);
searchBuilder.query(termQueryBuilder);
request.source(searchBuilder);
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
注意:termQuery()查询中文时,需要使用 属性.keyword
QueryBuilders.termQuery("name.keyword", "王五");
文档操作-高级查询(聚合操作)
1. 最大值 AggregationBuilders.max()
// 1.聚合操作-最大值
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
// 年龄 最大值 AggregationBuilders.max
AggregationBuilder aggregationBuilder =
AggregationBuilders.max("maxAge").field("age");
searchBuilder.aggregation(aggregationBuilder);
request.source(searchBuilder);
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}
2. 分组计数 AggregationBuilders.terms()
// 11.聚合操作-分组计数
SearchRequest request = new SearchRequest();
request.indices("user");
SearchSourceBuilder searchBuilder = new SearchSourceBuilder();
// 按年龄 进行分组计数
AggregationBuilder aggregationBuilder =
AggregationBuilders.terms("ageGroups").field("age");
searchBuilder.aggregation(aggregationBuilder);
request.source(searchBuilder);
// 查询
SearchResponse searchResponse = esClient.search(request, RequestOptions.DEFAULT);
System.out.println("查询耗时 : " + searchResponse.getTook());
// 查询结果遍历
SearchHits hits = searchResponse.getHits();
System.out.println("总记录数 : " + hits.getTotalHits());
for (SearchHit hit : hits) {
System.out.println(hit.getSourceAsString());
}