1.put和post都是提交數(shù)據(jù)轩勘,兩者的區(qū)別:put必須帶ID如果不帶ID直接報錯栈雳,如果ID已存在則是更新,ID不存在則是新增,POST可以不帶ID唱较,不帶ID則是新增扎唾。如果帶了ID,ID已存在則是修改南缓,ID不存在則是新增
2.get是查詢數(shù)據(jù)胸遇,在返回的結(jié)果中有_seq_no,并發(fā)控制字段汉形,每次更新都會+1纸镊,用來做樂觀鎖;_primary_term:同上概疆,主分片重新分配逗威,每次重啟都會分配新的數(shù)值,怎么使用呢岔冀,就是在url后面拼接上著兩個參數(shù)凯旭,例?if_seq_no=1&id_primary_term=1 如果這兩個數(shù)值都正確那么就會進(jìn)行更新,不正確就不會更新
3.更新操作post帶_update使套,如果和原來的數(shù)據(jù)一模一樣這樣就不進(jìn)行更新操作罐呼,seq_no,version_id都不會改變侦高,而且請求體中要在更新的內(nèi)容外面加一層"doc": {}嫉柴;put和post更新都不會檢查元素直接更新
4.批量操作post請求 url后面添加_bulk 請求體格式:
{action:{metadata}}
{requestbody};action指的是操作矫膨,metadata是指的是元數(shù)據(jù)(_index,_id等)requestbody是數(shù)據(jù)體差凹;批量操作沒有事物的說法,每個操作都是獨立的
4.查詢侧馅,可以在url中直接添加要查詢的參數(shù)危尿,也可將要查詢的條件寫到請求體中
get bank/_search
{
"query":{
"match_all": {}
},
"sort":[
{
"account_number": "asc"
},
{
"balance": "desc"
}
],
"from": 10,
"size": 10
"_source":["balance","firstname"] ###指定要查詢的列
}
根據(jù)某個字段進(jìn)行查詢,支持模糊查詢
"query": {
? ? "match": {
? ? ? "address": "kings"
? ? }
? }
進(jìn)行短語匹配馁痴,把后面的當(dāng)做一個短語一塊匹配
GET /bank/_search
{
? "query": {
? ? "match_phrase": {
? ? ? "address": "mill road"
? ? }
? }
}
多字段匹配谊娇,類似于數(shù)據(jù)庫中or,多字段中也是進(jìn)行分詞的
GET /bank/_search
{
? "query": {
? ? "multi_match": {
? ? ? "query": "mill",
? ? ? "fields": ["address","city"]
? ? }
? }
}
聯(lián)合查詢罗晕,這里面的should之后影響搜索的得分济欢,并不會影響結(jié)果。而must_not不會影響得分小渊,這個相當(dāng)于一個過濾器法褥,只會對結(jié)果有影響
GET /bank/_search
{
? "query": {
? ? "bool": {
? ? ? "must": [
? ? ? ? {"match": {
? ? ? ? ? "gender": "M"
? ? ? ? }},
? ? ? ? {
? ? ? ? ? "match": {
? ? ? ? ? ? "address": "mill"
? ? ? ? ? }
? ? ? ? }
? ? ? ],
? ? ? "must_not": [
? ? ? ? {"match": {
? ? ? ? ? "lastname": "wa"
? ? ? ? }}
? ? ? ],
? ? ? "should": [
? ? ? ? {"match": {
? ? ? ? ? "address": "1"
? ? ? ? }}
? ? ? ]
? ? }
? }
}
找出某個字段在某個范圍內(nèi)的記錄,這個結(jié)果是有得分的酬屉,當(dāng)把must換成filter時是沒有得分的
GET bank/_search
{
? "query": {
? ? "bool": {
? ? ? "must": [
? ? ? ? {
? ? ? ? ? "range": {
? ? ? ? ? ? "age": {
? ? ? ? ? ? ? "gte": 10,
? ? ? ? ? ? ? "lte": 20
? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ? }
? ? ? ]
? ? }
? }
}
如果是精準(zhǔn)的值的話半等,就用term(像年齡等)如果是文本的全文搜索的話用match揍愁,某個字段.keywords也是精確匹配的
聚合查詢,即對結(jié)果進(jìn)行一些分析比如求平均值杀饵,獲取數(shù)據(jù)分布等
格式:
? "aggs": {
? ? "agg_name": {
? ? ? "agg_類型(term:獲取數(shù)據(jù)的分布莽囤,avg平均值等)": {
? ? ? ? "field": "age",
? ? ? ? "size": 100
? ? ? }
}
可以agg可以多個同級,也可以作為下屬切距,將結(jié)果作為兩一個agg的入?yún)?/p>
例:獲取每個年齡的人數(shù)和工資的平均值
GET bank/_search
{
? "query": {
? ? "match_all": {}
? },
? "aggs": {
? ? "ageAgg": {
? ? ? "terms": {
? ? ? ? "field": "age",
? ? ? ? "size": 100
? ? ? },
? ? ? "aggs": {
? ? ? ? "ageAvg": {
? ? ? ? ? "avg": {
? ? ? ? ? ? "field": "balance"
? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? }
? }
}
映射:指的是索引中的數(shù)據(jù)的類型
GET bank/_mapping
創(chuàng)建一個索引的映射(keyword只能精確匹配朽缎,text可以全局索引,integer只能用term查詢)
PUT /my_index
{
? "mappings": {
? ? "properties": {
? ? ? "age":{"type": "integer"},
? ? ? "email":{"type": "keyword"},
? ? ? "name":{"type": "text"}
? ? }
? }
}
給一個index添加一個映射谜悟,index如果為false則是不讓根據(jù)這個字段進(jìn)行檢索
PUT /my_index/_mapping
{
? "properties": {
? ? ? "employee_id":{
? ? ? ? "type": "integer",
? ? ? ? "index": false
? ? ? }
? ? }
}
想要修改映射话肖,只能進(jìn)行數(shù)據(jù)遷移,先創(chuàng)建一個新的索引赌躺,然后進(jìn)行數(shù)據(jù)遷移
數(shù)據(jù)遷移(type在his中有):
POST _reindex
{
? "source": {
? ? "index": "bank",
? ? "type": "account"
? },
? "dest": {
? ? "index": "newbank"
? }
}
springboot 整合 elasticsearch client
引入依賴
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.2</version>
</dependency>
這里要記得修改elasticsearch的依賴狼牺,因為這個依賴springboot本身就有這個依賴,必須要替換成和客戶端相同的才行
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath></relativePath>
</parent>
<properties>
<elasticsearch.version>7.4.2</elasticsearch.version>
</properties>
進(jìn)行相關(guān)的配置
package com.yuchen.mailsearch.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MailElasticsearchConfig {
public static final RequestOptionsCOMMON_OPTIONS;
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
//? ? ? ? builder.addHeader("Authorization", "Bearer " + TOKEN);
//? ? ? ? builder.setHttpAsyncResponseConsumerFactory(
//? ? ? ? ? ? ? ? new HttpAsyncResponseConsumerFactory
//? ? ? ? ? ? ? ? ? ? ? ? .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
? ? ? ? COMMON_OPTIONS = builder.build();
}
@Bean
? ? public RestHighLevelClient esRestClient(){
RestHighLevelClient restHighLevelClient =new RestHighLevelClient(
RestClient.builder(
new HttpHost("192.168.56.10",9200,"http")
)
);
return restHighLevelClient;
}
}
進(jìn)行操作
package com.yuchen.mailsearch;
import com.alibaba.fastjson.JSON;
import com.yuchen.mailsearch.config.MailElasticsearchConfig;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.hibernate.validator.resourceloading.AggregateResourceBundleLocator;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MailSearchApplicationTests {
@Autowired
? ? RestHighLevelClientrestHighLevelClient;
@Test
? ? public void searchData()throws IOException {
SearchRequest searchRequest =new SearchRequest();
searchRequest.indices("bank");
SearchSourceBuilder searchSourceBuilder =new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("address","mill"));
//求年齡的值分布
? ? ? ? TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
searchSourceBuilder.aggregation(ageAgg);
//求平均工資
? ? ? ? AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
searchSourceBuilder.aggregation(balanceAvg);
System.out.println(searchSourceBuilder.toString());
searchRequest.source(searchSourceBuilder);
SearchResponse search =restHighLevelClient.search(searchRequest, MailElasticsearchConfig.COMMON_OPTIONS);
System.out.println(search.toString());
//分析結(jié)果
? ? ? ? SearchHits hits = search.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits){
String index = searchHit.getIndex();
String id = searchHit.getId();
float score = searchHit.getScore();
String sourceAsString = searchHit.getSourceAsString();
System.out.println("index"+index+"id"+id+"score"+score+"sourceAsString"+sourceAsString);
}
Aggregations aggregations = search.getAggregations();
Terms aggregation = aggregations.get("ageAgg");
for (Terms.Bucket bucket : aggregation.getBuckets()){
String keyAsString = bucket.getKeyAsString();
System.out.println("年齡" + keyAsString);
}
Avg aggregation1 = aggregations.get("balanceAvg");
System.out.println("平均薪資" + aggregation1.getValueAsString());
}
}