🌹 ElasticSearch 基础教程,请指教。
🌹🌹 如你对技术也感兴趣,欢迎交流。
🌹🌹🌹 如有对阁下帮助,请👍点赞💖收藏🐱🏍分享😀
理论
Elasticsearch是基于Apache Lucene的搜索服务器它的最新版本是8.10.2。
Elasticsearch是一个实时的分布式开放源代码全文本搜索和分析引擎。可从RESTful Web服务界面访问它,并使用无模式的JSON(JavaScript对象表示法)文档存储数据。它基于Java编程语言构建,因此Elasticsearch可以在不同平台上运行。它使用户能够以很高的速度浏览大量的数据。
Elasticsearch & MYSQL
索引
对比关系型数据库,创建索引就等同于创建数据库
创建
PUT /shopping
HTTP 的 PUT 请求
查看
单个索引
GET /shopping
HTTP 的 GET 请求
全部索引
GET /_cat/indices?v
HTTP 的 GET 请求
删除
DELETE /shopping
HTTP 的 DELETE 请求
文档
创建
随机ID
POST /shopping/_doc
{
"title":"华为meta60pro",
"category":"手机",
"images":"https://www.gulixueyuan.com/xm.jpg",
"price":"6499.00"
}
自定义ID
POST /shopping/_doc/1000
{
"title":"华为meta60pro max",
"category":"手机",
"images":"https://www.gulixueyuan.com/xm.jpg",
"price":"7499.00"
}
PUT /shopping/_doc/1002
{
"title":"华为meta60pro max尊享",
"category":"手机",
"images":"https://www.gulixueyuan.com/xm.jpg",
"price":"8499.00"
}
查询
主键查询
不存在查询
全部查询
GET /shopping/_search
修改
全量更新
PUT /shopping/_doc/1002
{
"title":"华为meta60pro max尊享",
"category":"手机",
"images":"https://www.gulixueyuan.com/xm.jpg",
"price":"12999.00"
}
修改
修改后
局部更新
POST /shopping/_update/1002
{
"doc":{
"title":"华为meta70pro max尊享"
}
}
删除
DELETE /shopping/_doc/1000
复杂查询
请求路径方式
GET /shopping/_search?q=category:手机
请求体方式
属性查询
GET /shopping/_search
{
"query":{
"match": {
"category": "手机"
}
}
}
全量查询
GET /shopping/_search
{
"query":{
"match_all": {}
}
}
分页查询
GET /shopping/_search
{
"query":{
"match_all": {}
},
"from": 1,
"size": 2
}
指定返回属性
GET /shopping/_search
{
"query":{
"match_all": {}
},
"from": 1,
"size": 2,
"_source": ["price","title"]
}
排序
GET /shopping/_search
{
"query":{
"match_all": {}
},
"from": 1,
"size": 2,
"_source": ["title"],
"sort": [
{
"title": {
"order": "desc"
}
}
]
}
错误
# 设置属性类型
PUT shopping/_mapping
{
"properties": {
"price": {
"type": "text"
},
"title": {
"fielddata": true,
"type": "text"
}
}
}
查询结果
组合查询
同时满足所有条件
## SQL: category="手机" AND price="6499.00"
GET /shopping/_search
{
"query":{
"bool": {
"must": [
{
"match": {
"category": "手机"
}
},
{
"match": {
"price": "6499.00"
}
}
]
}
}
}
满足某个条件
## SQL: category="手机" OR price="6499.00"
GET /shopping/_search
{
"query":{
"bool": {
"should": [
{
"match": {
"category": "手机"
}
},
{
"match": {
"price": "6499.00"
}
}
]
}
}
}
范围查询
## SQL: (category="手机" OR price=6499.00) and (price between 6500 and 10000)
GET /shopping/_search
{
"query":{
"bool": {
"should": [
{
"match": {
"category": "手机"
}
},
{
"match": {
"price": 6499.00
}
}
],
"filter": {
"range": {
"price": {
"gt": 6500,
"lt": 10000
}
}
}
}
}
}
分页排序
# SQL: (category="手机" OR price=6499.00) and (price between 6500 and 10000) limit 2 order by price desc
GET /shopping/_search
{
"query":{
"bool": {
"should": [
{
"match": {
"category": "手机"
}
},
{
"match": {
"price": 6499.00
}
}
],
"filter": {
"range": {
"price": {
"gt": 6500,
"lt": 10000
}
}
}
}
},
"from": 0,
"size": 2,
"sort": [
{
"price": {
"order": "desc"
}
}
]
}
高亮显示
GET /shopping/_search
{
"query":{
"match_phrase": {
"category": "手机"
}
},
"highlight": {
"fields": {
"category": {}
}
}
}
聚合查询
分组聚合
GET /shopping/_search
{
"aggs": {
"cacl_avg": {
"terms": {
"field":"price"
}
}
},
"size": 0
}
计算平均值
GET /shopping/_search
{
"aggs": {
"cacl_avg": {
"avg": {
"field":"price"
}
}
},
"size": 0
}
创建映射关系
映射关系
PUT /user/_mapping
{
"properties": {
"user":{
"type": "text",
"index": true
},
"sex":{
"type": "keyword",
"index": false
},
"tel":{
"type": "keyword",
"index": true
}
}
}
数据
分词查询(type=text)
关键字查询 (type=keyword)
未被索引,不允许查询
总结
type=text ,index=true 时,可分词可查询;
type=keyword ,index=true 时,不可分词可查询;
index=false 时,不可查询
Java API
Maven
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.8.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
客户端
public class ElasticSearchClient {
/**
* 创建对象
*
* @param host 地址
* @param port 端口
*/
public static RestHighLevelClient getElasticSearchClient() {
String host="127.0.0.1";
int port=9200;
String scheme="http";
return new RestHighLevelClient(
RestClient.builder(new HttpHost(host, port,scheme)));
}
/**
* 关闭
*
* @param client 客户端对象
*/
public static void closeClient(RestHighLevelClient client) {
try {
client.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
创建索引
/**
* 创建索引
*
* @param index 索引名
* RestHighLevelClient restHighLevelClient = ElasticSearchClient.getElasticSearchClient();
*/
public static void createIndex(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
CreateIndexRequest request = new CreateIndexRequest(index);
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
boolean acknowledged = createIndexResponse.isAcknowledged();
System.out.println("索引操作:" + acknowledged);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
查询索引
/**
* 查询索引
*
* @param index 索引名
*/
public static void findIndex(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
GetIndexRequest request = new GetIndexRequest(index);
GetIndexResponse getIndexResponse = restHighLevelClient.indices().get(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(getIndexResponse.getAliases());
System.out.println(getIndexResponse.getMappings());
System.out.println(getIndexResponse.getSettings());
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
删除索引
/**
* 删除索引
*
* @param index 索引名
*/
public static void deleteIndex(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
DeleteIndexRequest request = new DeleteIndexRequest(index);
AcknowledgedResponse response = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.isAcknowledged());
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
文档
创建文档
/**
* 创建文档
*
* @param index 索引
* @param id id
* @param source Json对象
*/
public static void addDoc(RestHighLevelClient restHighLevelClient, String index, String id, Object source) {
try {
//创建索引
IndexRequest indexRequest = new IndexRequest();
indexRequest.index(index).id(id);
indexRequest.source(JSONUtil.toJsonPrettyStr(source), XContentType.JSON);
IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(indexResponse.status());
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
修改文档
/**
* 修改数据
*
* @param index 索引
* @param id id
* @param source Json对象
*/
public static void updateDoc(RestHighLevelClient restHighLevelClient, String index, String id, Map<String, Object> source) {
try {
//创建索引
UpdateRequest request = new UpdateRequest();
request.index(index).id(id);
request.doc(source, XContentType.JSON);
UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.status());
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
查询文档
/**
* 查询数据
*
* @param index 索引
* @param id id
*/
public static void findDoc(RestHighLevelClient restHighLevelClient, String index, String id) {
try {
//创建索引
GetRequest request = new GetRequest();
request.index(index).id(id);
GetResponse getResponse = restHighLevelClient.get(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(getResponse.getSourceAsString());
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
删除文档
/**
* 查询数据
*
* @param index 索引
* @param id id
*/
public static void delDoc(RestHighLevelClient restHighLevelClient, String index, String id) {
try {
//创建索引
DeleteRequest request = new DeleteRequest();
request.index(index).id(id);
DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getResult());
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
批量文档
创建文档
/**
* 创建文档
*
* @param index 索引
* @param id id
* @param sources 数组
*/
public static void addDoc(RestHighLevelClient restHighLevelClient, String index, List<String> ids, List<Object> sources) {
try {
//创建索引
BulkRequest request = new BulkRequest();
int size = Math.min(ids.size(), sources.size());
for (int i = 0; i < size; i++) {
request.add(new IndexRequest().index(index).id(ids.get(i)).source(JSONUtil.toJsonPrettyStr(sources.get(i)), XContentType.JSON));
}
BulkResponse bulk = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(bulk.status());
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
删除文档
/**
* 删除数据
*
* @param index 索引
* @param ids id
*/
public static void delDoc(RestHighLevelClient restHighLevelClient, String index, List<String> ids) {
try {
//创建索引
BulkRequest request = new BulkRequest();
for (String id : ids) {
request.add(new DeleteRequest().index(index).id(id));
}
BulkResponse bulk = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(bulk.status());
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
高级查询
全量查询
/**
* 全量查询
*
* @param index 索引
*/
public static void completeSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsString());
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
条件查询
/**
* 条件查询
*
* @param index 索引
*/
public static void pageSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.termQuery("age", "16"));
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsString());
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
分页查询
/**
* 分页查询
*
* @param index 索引
*/
public static void pageSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
searchSourceBuilder.from(0);
searchSourceBuilder.size(5);
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsString());
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
排序查询
/**
* 排序查询
*
* @param index 索引
*/
public static void sortSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
searchSourceBuilder.from(0);
searchSourceBuilder.size(4);
searchSourceBuilder.sort("age", SortOrder.DESC);
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsString());
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
返回属性查询
/**
* 过滤查询
*
* @param index 索引
*/
public static void filterSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
// 过滤
String[] includes = {"name"};
String[] excludes = {};
searchSourceBuilder.fetchSource(includes, excludes);
// 分页
searchSourceBuilder.from(0);
searchSourceBuilder.size(4);
// 排序
searchSourceBuilder.sort("age", SortOrder.DESC);
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsString());
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
组合查询
/**
* 组合查询
*
* @param index 索引
*/
public static void combinationSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// boolQueryBuilder.must(QueryBuilders.matchQuery("age","19"));
// boolQueryBuilder.must(QueryBuilders.matchQuery("name","lisi"));
// boolQueryBuilder.mustNot(QueryBuilders.matchQuery("sex","女"));
boolQueryBuilder.should(QueryBuilders.matchQuery("age","19"));
boolQueryBuilder.should(QueryBuilders.matchQuery("age","20"));
searchSourceBuilder.query(boolQueryBuilder);
// 过滤
String[] includes = {"name","age"};
String[] excludes = {};
searchSourceBuilder.fetchSource(includes, excludes);
// 分页
searchSourceBuilder.from(0);
searchSourceBuilder.size(4);
// 排序
searchSourceBuilder.sort("age", SortOrder.DESC);
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsString());
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
范围查询
/**
* 范围查询
*
* @param index 索引
*/
public static void rangeSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age").gt(16).lt(28);
boolQueryBuilder.filter(rangeQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
// 过滤
String[] includes = {"name","age"};
String[] excludes = {};
searchSourceBuilder.fetchSource(includes, excludes);
// 分页
searchSourceBuilder.from(0);
searchSourceBuilder.size(2);
// 排序
searchSourceBuilder.sort("age", SortOrder.DESC);
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsString());
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
模糊查询
/**
* 模糊查询
*
* @param index 索引
*/
public static void vagueSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 模糊条件
searchSourceBuilder.query(QueryBuilders.fuzzyQuery("name","wangwu").fuzziness(Fuzziness.TWO));
// 过滤
String[] includes = {"name","age"};
String[] excludes = {};
searchSourceBuilder.fetchSource(includes, excludes);
// 分页
searchSourceBuilder.from(0);
searchSourceBuilder.size(2);
// 排序
searchSourceBuilder.sort("age", SortOrder.DESC);
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit.getSourceAsString());
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
高亮查询
/**
* 高亮查询
*
* @param index 索引
*/
public static void highSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 模糊条件
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "wangwu");
HighlightBuilder highlightBuilder=new HighlightBuilder();
highlightBuilder.preTags("<font color='red'>").postTags("</font>").field("name");
searchSourceBuilder.highlighter(highlightBuilder);
searchSourceBuilder.query(termQueryBuilder);
// 过滤
// String[] includes = {"name","age"};
// String[] excludes = {};
// searchSourceBuilder.fetchSource(includes, excludes);
// 分页
searchSourceBuilder.from(0);
searchSourceBuilder.size(2);
// 排序
searchSourceBuilder.sort("age", SortOrder.DESC);
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (SearchHit hit : response.getHits().getHits()) {
System.out.println(hit);
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
聚合查询
/**
* 聚合查询
*
* @param index 索引
*/
public static void polymerizationSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MaxAggregationBuilder maxAggregationBuilder = AggregationBuilders.max("MaxAge").field("age");
searchSourceBuilder.aggregation(maxAggregationBuilder);
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (Aggregation aggregation : response.getAggregations()) {
System.out.println(JSONUtil.toJsonPrettyStr(aggregation));
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
测试
分组查询
/**
* 分组查询
*
* @param index 索引
*/
public static void groupSearch(RestHighLevelClient restHighLevelClient, String index) {
try {
//创建索引
SearchRequest request = new SearchRequest();
request.indices(index);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");
searchSourceBuilder.aggregation(termsAggregationBuilder);
request.source(searchSourceBuilder);
SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
System.out.println("------------------------------------------------");
System.out.println(response.getHits().getTotalHits());
for (Aggregation aggregation : response.getAggregations()) {
System.out.println(JSONUtil.toJsonPrettyStr(aggregation));
}
System.out.println("------------------------------------------------");
} catch (IOException e) {
throw new RuntimeException(e);
}
}