ElasticSearch
Elastic Stack 包括 Elasticsearch、Kibana、Beats、Logstash。能够安全可靠的获取任何来源、任何格式的数据,然后实时的对数据进行搜索、分析、可视化。
ES 是一个开源的高扩展的分布式的全文搜索引擎,是整个 Elastic Stack 技术栈的核心。它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理 PB 级别的数据。
Lucene
Lucene 提供了一个简单却强大的应用程式接口,能够做全文索引和搜索。在 Java 开发环境里 Lucene 是一个成熟的、免费开源工具。但 Lucene 只是一个提供全文搜索功能类库的核心工具包,而真正使用它还需要一个完善的服务框架搭建起来进行应用。
数据格式
ES 是面向文档型数据库,一条数据相当于一个文档。
HTTP操作
-
创建索引
http://localhost:9200/shopping [PUT]
-
创建文档
http://localhost:9200/shopping/_doc [POST]
-
根据 ID 查询
http://localhost:9200/shopping/_doc/[ID] [GET]
-
查询所有
http://localhost:9200/shopping/_search [GET]
-
根据 ID 全量数据更新
http://localhost:9200/shopping/_doc/[ID] [PUT]
-
根据 ID 局部数据更新
http://localhost:9200/shopping/_update/[ID] [POST]
-
根据 ID 删除
http://localhost:9200/shopping/_doc/[ID] [DELETE]
-
条件查询
http://localhost:9200/shopping/_search?q=name:zh [GET] 或者 http://localhost:9200/shopping/_search [GET] { "query" : { "match" : { "name" : "zh" } } } http://localhost:9200/shopping/_search [GET] { "query" : { "bool" : { "must" : [{ "match" : { "name" : "zh" } }] } } } // 完全匹配 { "query" : { "match_phrase" : { "name" : "zh" } } } // 聚合 { "aggs" : { // 聚合操作 "price_group" : { // 分组名称 "terms" : { // 分组 "filed" : "price" // 分组字段 } } }, "size" : 0 // 不需要返回原始数据 } // 平均值 { "aggs" : { // 聚合操作 "price_avg" : { // 分组名称 "avg" : { // 平均值 "filed" : "price" // 分组字段 } } }, "size" : 0 // 不需要返回原始数据 }
-
分页查询
http://localhost:9200/shopping/_search { "query" : { "match_all" : { } } , "from" : 0, "size" : 3 }
-
指定参数查询
http://localhost:9200/shopping/_search { "query" : { "match_all" : { } } , "_source" : ["name"] }
-
查询结果排序
http://localhost:9200/shopping/_search { "query" : { "match_all" : { } } , "sort" : { "price" : { "order" : "asc" } } }
-
建立映射
http://localhost:9200/user/_mapping [PUT] { "properties" : { "name" : { "type" : "text", "index" : true }, "sex" : { "type" : "keyword", "index" : true }, "tel" : { "type" : "keyword", "index" : false } } }
API 使用
import java.io.IOException;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.FuzzyQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.MaxAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @author zhanghui07 <zhanghui07@kuaishou.com>
* Created on 2021-09-16
* @description:
*/
public class Test {
private void creat(RestHighLevelClient esClient) throws IOException {
System.out.println("创建索引");
CreateIndexRequest createIndexRequest = new CreateIndexRequest("user");
CreateIndexResponse createIndexResponse = esClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
boolean acknowledged = createIndexResponse.isAcknowledged();
System.out.println(acknowledged);
}
private void get(RestHighLevelClient esClient) throws IOException {
System.out.println("获取索引");
GetIndexRequest getIndexRequest = new GetIndexRequest("person");
GetIndexResponse getIndexResponse = esClient.indices().get(getIndexRequest, RequestOptions.DEFAULT);
System.out.println(getIndexResponse.getAliases());
System.out.println(getIndexResponse.getMappings());
System.out.println(getIndexResponse.getSettings());
}
private void del(RestHighLevelClient esClient) throws IOException {
System.out.println("删除索引");
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("user");
AcknowledgedResponse delete = esClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
private void add(RestHighLevelClient esClient) throws IOException {
System.out.println("插入数据");
IndexRequest indexRequest = new IndexRequest();
indexRequest.index("user").id("1007");
User user = new User("wangwu4", 30, "男");
ObjectMapper objectMapper = new ObjectMapper();
String string = objectMapper.writeValueAsString(user);
indexRequest.source(string, XContentType.JSON);
IndexResponse response = esClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println(response.getResult());
}
private void update(RestHighLevelClient esClient) throws IOException {
System.out.println("修改数据");
UpdateRequest updateRequest = new UpdateRequest();
updateRequest.index("user").id("1001");
updateRequest.doc(XContentType.JSON, "sex", "女");
UpdateResponse updateResponse = esClient.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(updateResponse.getResult());
}
private void getDoc(RestHighLevelClient esClient) throws IOException {
System.out.println("查询数据");
GetRequest getRequest = new GetRequest();
getRequest.index("user").id("1001");
GetResponse response = esClient.get(getRequest, RequestOptions.DEFAULT);
System.out.println(response.getSourceAsString());
}
private void delDoc(RestHighLevelClient esClient) throws IOException {
System.out.println("删除数据");
DeleteRequest deleteRequest = new DeleteRequest();
deleteRequest.index("user").id("1001");
DeleteResponse response = esClient.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(response.getResult());
}
private void batchAdd(RestHighLevelClient esClient) throws IOException {
System.out.println("批量插入数据");
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.add(new IndexRequest().index("user").id("1001")
.source(XContentType.JSON, "name", "zhangsan", "age", 30, "sex", "男"));
bulkRequest.add(new IndexRequest().index("user").id("1002")
.source(XContentType.JSON, "name", "lisi", "age", 30, "sex", "女"));
bulkRequest.add(new IndexRequest().index("user").id("1003")
.source(XContentType.JSON, "name", "wangwu", "age", 40, "sex", "男"));
bulkRequest.add(new IndexRequest().index("user").id("1004")
.source(XContentType.JSON, "name", "wangwu", "age", 40, "sex", "女"));
bulkRequest.add(new IndexRequest().index("user").id("1005")
.source(XContentType.JSON, "name", "wangwu", "age", 50, "sex", "男"));
bulkRequest.add(new IndexRequest().index("user").id("1006")
.source(XContentType.JSON, "name", "wangwu", "age", 50, "sex", "男"));
BulkResponse response = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(response.getTook());
System.out.println(response.getItems());
}
private void batchDel(RestHighLevelClient esClient) throws IOException {
System.out.println("批量删除数据");
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.add(new DeleteRequest().index("user").id("1001"));
bulkRequest.add(new DeleteRequest().index("user").id("1002"));
bulkRequest.add(new DeleteRequest().index("user").id("1003"));
BulkResponse response = esClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(response.getTook());
System.out.println(response.getItems());
}
private void queryAll(RestHighLevelClient esClient) throws IOException {
System.out.println("全量查询数据");
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
System.out.println(response.getTook());
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
private void querySelective(RestHighLevelClient esClient) throws IOException {
System.out.println("条件查询数据");
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.termQuery("age", 30));
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
System.out.println(response.getTook());
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
private void queryPage(RestHighLevelClient esClient) throws IOException {
System.out.println("分页查询数据");
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
searchSourceBuilder.from(0);
searchSourceBuilder.size(2);
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
System.out.println(response.getTook());
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
private void querySort(RestHighLevelClient esClient) throws IOException {
System.out.println("排序查询数据");
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
searchSourceBuilder.sort("age", SortOrder.DESC);
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
System.out.println(response.getTook());
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
private void queryFilter(RestHighLevelClient esClient) throws IOException {
System.out.println("过滤查询数据");
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
String[] includes = {"name"};
String[] excludes = {};
searchSourceBuilder.fetchSource(includes, excludes);
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
System.out.println(response.getTook());
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
private void zuheFilter(RestHighLevelClient esClient) throws IOException {
System.out.println("组合查询数据");
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.mustNot(QueryBuilders.matchQuery("sex", "男"));
RangeQueryBuilder range = QueryBuilders.rangeQuery("age");
range.gt(0);
range.lt(100);
FuzzyQueryBuilder fuzziness = QueryBuilders.fuzzyQuery("name", "wangwu").fuzziness(Fuzziness.ONE);
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "zhangsan");
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<font color = 'red' >");
highlightBuilder.postTags("</font>");
// 多个 query 条件会以最后一个为准
SearchSourceBuilder searchSourceBuilder =
new SearchSourceBuilder().query(boolQueryBuilder).query(range).query(fuzziness).query(termQueryBuilder)
.highlighter(highlightBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
System.out.println(response.getTook());
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
private void aggrFilter(RestHighLevelClient esClient) throws IOException {
System.out.println("聚合查询数据");
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MaxAggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age");
searchSourceBuilder.aggregation(aggregationBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
System.out.println(response.getTook());
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
private void groupFilter(RestHighLevelClient esClient) throws IOException {
System.out.println("分组查询数据");
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("user");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
AggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");
searchSourceBuilder.aggregation(aggregationBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println(hits.getTotalHits());
System.out.println(response.getTook());
for (SearchHit searchHit : hits) {
System.out.println(searchHit.getSourceAsString());
}
}
public static void main(String[] args) throws IOException {
RestHighLevelClient esClient = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
new Test().groupFilter(esClient);
esClient.close();
}
}