REST介紹
REST(REpresentational State Transfer),字面意思為“表述性狀態(tài)傳輸”,一種開發(fā)的約定。
REST約定用HTTP的請(qǐng)求頭POST、GET、PUT、DELETE正好對(duì)應(yīng)CRUD(Create、Read、Update、Delete)四種數(shù)據(jù)操作。
索引、映射的建立
索引的建立:
curl -X PUT http://localhost:9200/hospital/
{
"settings": {
"number_of_shards": 1,//分片數(shù)量
"number_of_replicas": 0//副本分片數(shù)量
}
}
映射的建立:
curl -X PUT http://localhost:9200/hospital/_mapping/medicine2?pretty
{
"dynamic": false,
"properties": {
"standardName": {
"type": "text",
"index": "analyzed"
},
"pattern": {
"type": "text"
},
"validDate": {
"type": "keyword"
}
}
}
1、DSL篇
可以在java中輸出SearchQueryBuilder,來(lái)查看對(duì)應(yīng)的DSL(json格式)。
在ES中進(jìn)行查詢,默認(rèn)的分詞器對(duì)于單個(gè)漢字都會(huì)進(jìn)行分詞,標(biāo)點(diǎn)符號(hào)不計(jì)入分詞,以空格來(lái)間隔英語(yǔ)單詞。對(duì)于not_analyzed不計(jì)入分詞器,只能全部搜索(或者用通配符查詢、前綴查詢)。對(duì)于計(jì)入分詞的,term、match*(match系列)、querystring都支持,而且查詢比較良好。keyword或者數(shù)字類型,都只支持整個(gè)匹配。
說(shuō)一說(shuō)分頁(yè),分頁(yè)都深度分頁(yè)和游標(biāo)分頁(yè)。
深度分頁(yè)是每一次都會(huì)從最新的數(shù)據(jù)中進(jìn)行查詢。適合于實(shí)時(shí)查詢分頁(yè)。因?yàn)樯疃确猪?yè)與CPU、IO、帶寬、內(nèi)存都有關(guān)。所以需要限制深度分頁(yè)的頁(yè)數(shù),防止因?yàn)橐陨显颍ɑ蚺老x)造成卡頓或者宕機(jī)。
游標(biāo)分頁(yè)是在你查詢時(shí),會(huì)初始化一個(gè)快照,在遍歷時(shí),從這個(gè)快照里取數(shù)據(jù),也就是說(shuō),在初始化后對(duì)索引插入、刪除、更新數(shù)據(jù)都不會(huì)影響遍歷結(jié)果。適用于后端對(duì)于數(shù)據(jù)的大批量分析。
2、JAVA篇
以下所有的方法都寫重點(diǎn)部分,需要樣例,請(qǐng)參見(jiàn)GitHub:https://github.com/lingbao08/springboot-example.git。
1. 創(chuàng)建查詢?nèi)萜?/h5>
//此容器可以放置所有的queryBuilder
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
1. 查詢字符串
//精確查詢,查詢有該分詞的文檔
QueryBuilder termQuery = QueryBuilders.termQuery(field, value);
//字符串查詢,查詢包含該分詞的文檔(英文只針對(duì)于單詞,中文可能會(huì)拆開該詞語(yǔ):策略視分詞器而定)
QueryBuilder termQuery = QueryBuilders.queryStringQuery(value)
.field(field,2f);//可以指定單字段,也可以不指定,不指定按照默認(rèn)字段查詢
// .fields(map)//多個(gè)字段
2.查詢范圍值
//可以只選大于而不選小于。可以用于查詢?nèi)掌?、?shù)字、字符串等。
//比較日期時(shí)注意和數(shù)據(jù)庫(kù)格式一致
//不包含的范圍查詢
QueryBuilder range = QueryBuilders.rangeQuery(field).gt(0).lt(11);
//包含的范圍查詢
QueryBuilder range = QueryBuilders.rangeQuery(field).from(0).to(11);
3.IN查詢
QueryBuilder terms = QueryBuilders.termsQuery("id", idList);
2.多字段匹配單值
MultiMatchQueryBuilder builder = QueryBuilders.multiMatchQuery(value, fields);
3.單(多)字段匹配多值
//構(gòu)建匹配字段及其優(yōu)先級(jí)
Map<String,Float> map = new HashMap();
int length = fields.length;
for (int i = 0; i < length; i++) {
map.put(fields[i],Float.valueOf(length-i));
}
//其中value中,eg:“A 神經(jīng) FFF” 表示這三個(gè)都搜索。
QueryBuilder termQuery = QueryBuilders.queryStringQuery(value).fields(map);
4.查詢指定想要的字段(或不想要的字段)
SearchRequestBuilder srb = esClient.prepareSearch(indexName)
.setFetchSource(shows, null);//關(guān)鍵方法,前面為想要的字段,后面為不想要的字段
5.排序
SortBuilder sort = SortBuilders.fieldSort(field).order(SortOrder.ASC);
SortBuilders.scoreSort();//得分權(quán)重排序
//多個(gè)排序可以按照順序來(lái)添加
SearchRequestBuilder srb = esClient.prepareSearch(indexName)
.addSort(defaultScoreSort()).addSort(sort);
4.計(jì)總數(shù)
ValueCountAggregationBuilder aggregation =
AggregationBuilders.count("count").field(field);
SearchRequestBuilder sr = esClient.prepareSearch(indexName).addAggregation(aggregation);
if (CollectionUtils.isNotEmpty(conditions))
sr = sr.setQuery(builderQueries(conditions));
SearchResponse response = sr.execute().get();
ValueCount count = response.getAggregations().get("count");
return count.getValue();
6.分頁(yè)
//此容器可以放置所有的queryBuilder
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//精確查詢,查詢有該分詞的文檔
QueryBuilder termQuery = QueryBuilders.termQuery(field, value);
//字符串查詢,查詢包含該分詞的文檔(英文只針對(duì)于單詞,中文可能會(huì)拆開該詞語(yǔ):策略視分詞器而定)
QueryBuilder termQuery = QueryBuilders.queryStringQuery(value)
.field(field,2f);//可以指定單字段,也可以不指定,不指定按照默認(rèn)字段查詢
// .fields(map)//多個(gè)字段
//可以只選大于而不選小于。可以用于查詢?nèi)掌?、?shù)字、字符串等。
//比較日期時(shí)注意和數(shù)據(jù)庫(kù)格式一致
//不包含的范圍查詢
QueryBuilder range = QueryBuilders.rangeQuery(field).gt(0).lt(11);
//包含的范圍查詢
QueryBuilder range = QueryBuilders.rangeQuery(field).from(0).to(11);
QueryBuilder terms = QueryBuilders.termsQuery("id", idList);
MultiMatchQueryBuilder builder = QueryBuilders.multiMatchQuery(value, fields);
//構(gòu)建匹配字段及其優(yōu)先級(jí)
Map<String,Float> map = new HashMap();
int length = fields.length;
for (int i = 0; i < length; i++) {
map.put(fields[i],Float.valueOf(length-i));
}
//其中value中,eg:“A 神經(jīng) FFF” 表示這三個(gè)都搜索。
QueryBuilder termQuery = QueryBuilders.queryStringQuery(value).fields(map);
SearchRequestBuilder srb = esClient.prepareSearch(indexName)
.setFetchSource(shows, null);//關(guān)鍵方法,前面為想要的字段,后面為不想要的字段
SortBuilder sort = SortBuilders.fieldSort(field).order(SortOrder.ASC);
SortBuilders.scoreSort();//得分權(quán)重排序
//多個(gè)排序可以按照順序來(lái)添加
SearchRequestBuilder srb = esClient.prepareSearch(indexName)
.addSort(defaultScoreSort()).addSort(sort);
ValueCountAggregationBuilder aggregation =
AggregationBuilders.count("count").field(field);
SearchRequestBuilder sr = esClient.prepareSearch(indexName).addAggregation(aggregation);
if (CollectionUtils.isNotEmpty(conditions))
sr = sr.setQuery(builderQueries(conditions));
SearchResponse response = sr.execute().get();
ValueCount count = response.getAggregations().get("count");
return count.getValue();
在ES中分頁(yè)有兩種,一種是靜態(tài)分頁(yè)(又稱游標(biāo)分頁(yè)),一種動(dòng)態(tài)分頁(yè)(又稱深度分頁(yè))。
具體采用哪種分頁(yè),請(qǐng)參考上面DSL部分。
動(dòng)態(tài)分頁(yè):
SearchRequestBuilder srb = esClient.prepareSearch(indexName)
.setFrom(from).setSize(pageSize);
靜態(tài)分頁(yè)(取自官網(wǎng)):
SearchResponse scrollResp = esClient.prepareSearch(indexName)
.addSort(sort)
.setScroll(new TimeValue(60000))//search context存活時(shí)間
.setQuery(builderQueries(conditions))
.setFrom(from).setSize(pageSize).get(); //max of 100 hits will be returned for each scroll
//Scroll until no hits are returned
do {
for (SearchHit hit : scrollResp.getHits().getHits()) {
//Handle the hit...
}
scrollResp = esClient.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();
}
while (scrollResp.getHits().getHits().length != 0); // Zero hits mark the end of the scroll and the while loop.
5.插入單條
IndexResponse response = this.esClient.prepareIndex(indexName, typeName).setSource(objectMapper.writeValueAsBytes(t), XContentType.JSON).get();
if (responses.status() == RestStatus.OK) return true;
6.批量插入
BulkRequestBuilder bulkRequestBuilder = this.esClient.prepareBulk();
for (T t : list) {
IndexRequestBuilder indexRequestBuilder = esClient.prepareIndex(indexName, typeName).setSource(objectMapper.writeValueAsBytes(t), XContentType.JSON);
bulkRequestBuilder.add(indexRequestBuilder);
}
BulkResponse responses = bulkRequestBuilder.execute().actionGet();
if (responses.status() == RestStatus.OK) return true;
7.更新(單條)
UpdateResponse response = this.esClient.prepareUpdate(indexName, typeName, esId)
.setDoc(objectMapper.writeValueAsBytes(t), XContentType.JSON).get();
if (response.status() == RestStatus.OK) return true;
8.刪除
BulkByScrollResponse response = DeleteByQueryAction.INSTANCE
.newRequestBuilder(esClient).source(indexName)
.filter(builderQueries(conditions)).get();
參考鏈接:https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.6/index.html。
中文分詞
參見(jiàn)優(yōu)化篇——中文分詞。
分詞包的使用
最近正在破解搜狗的scel文件,loading。。。。。。