1. Client
說明:Client是Elasticsearch所有API的主入口,主要方法有:
AdminClient admin() | 獲取ES管理客戶端 |
GetRequestBuilder prepareGet() | 準備一個GET請求 |
IndexRequestBuilder prepareIndex(String index, String type) | 準備一個新增文檔的請求 |
DeleteRequestBuilder prepareDelete() | 準備一個刪除文檔的請求 |
BulkRequestBuilder prepareBulk() | 準備一個批量操作的請求 |
SearchRequestBuilder prepareSearch(String... indices) | 準備一個查詢請求 |
UpdateRequestBuilder prepareUpdate() | 準備一個更新的請求(更新的本質是先查詢索引替換更新的值後進行替換,所以反而比插入更耗性能) |
AdminClient
說明:對ES進行管理的客戶端,主要方法有:
ClusterAdminClient cluster() | 產生一個允許從集羣中執行action或操作的client |
IndicesAdminClient indices() | 產生一個允許從索引中執行action或操作的client |
IndicesAdminClient
說明:對ES的index進行管理的客戶端,主要方法有:
IndicesExistsRequestBuilder prepareExists(String... indices) | 準備一個判斷索引是否存在的請求 |
TypesExistsRequestBuilder prepareTypesExists(String... index) | 準備一個判斷類型是否存在的請求 |
CreateIndexRequestBuilder prepareCreate(String index) | 準備一個創建索引的請求 |
DeleteIndexRequestBuilder prepareDelete(String... indices) | 準備一個刪除索引的請求 |
AnalyzeRequestBuilder prepareAnalyze(@Nullable String index, String text) | 準備一個對字符串進行分詞的請求 |
PutIndexTemplateRequestBuilder preparePutTemplate(String name) | 準備一個設置模板的請求 |
DeleteIndexTemplateRequestBuilder prepareDeleteTemplate(String name) | 準備一個刪除模板的請求 |
UpdateSettingsRequestBuilder prepareUpdateSettings(String... indices) | 準備一個更新設置的請求,如更新副本數量等 |
PutMappingRequestBuilder preparePutMapping(String... indices) | 準備一個新建映射關係的請求 |
QueryBuilders
說明:爲prepareSearch組裝查詢參數,如:
Java代碼
- client.prepareSearch(esIndex).setTypes(esType).setQuery(QueryBuilders.matchQuery("global_ana_ch", "杭州西湖")).setFrom(0).setSize(1).get();
matchAllQuery() | 構造匹配所有文檔的查詢 |
matchQuery(String name, Object text) | 構造查詢一個被分析器分析過的字段的查詢(match查詢) |
matchPhraseQuery(String name, Object text) | 它和matchQuery的區別是它不會對傳入的參數(text)進行分詞,而是以其做爲一個完整的詞進行查詢(類似百度查詢時加引號的功能)如“有限公司”會分詞成“有限”和“公司”,根據分詞規則,“有限企業”、“大公司”這樣的數據也會被查詢出來,使用此方法後則必須包含“有限公司”纔會被查詢出 |
matchPhrasePrefixQuery(String name, Object text) | 中文查詢時matchPhraseQuery和matchPhrasePrefixQuery並沒有什麼區別,英文查詢時matchPhrasePrefixQuery會以短語形式查詢,查詢時關鍵字不會被分詞,而是直接以一個字符串的形式查詢 |
commonTermsQuery(String name, Object text) | 對query進行重寫,區分低頻詞和高頻詞,並根據Elasticsearch傳遞的highFreqOccur和lowFreqOccur將高頻詞和低頻詞構造成BooleanQuery它的好處是減少了對高頻詞(如and)查詢的性能影響,增加的查詢效率 |
termQuery(String name, Object value) | 多字段查詢 |
termsQuery(String name, Object... values) | 和termQuery類似,多個term組合 |
fuzzyQuery(String name, Object value) | 模糊查詢(like) |
prefixQuery(String name, String prefix) | 前綴匹配查詢 |
rangeQuery(String name) | 範圍區間查詢 |
wildcardQuery(String name, String query) | 使用通配符查詢(*,?) |
regexpQuery(String name, String regexp) | 正則查詢org.apache.lucene.util.automaton.RegExp |
queryStringQuery(String queryString) | 字符串查詢 |
boolQuery() | 布爾型判斷的查詢must::多個查詢條件的完全匹配,相當於 andmustNot::多個查詢條件的相反匹配,相當於 notshould::至少有一個查詢條件匹配, 相當於 or |
SpanQuery | SpanQuery是按照詞在文章中的距離或者查詢幾個相鄰詞的查詢。 |
spanFirstQuery | 接受另一個跨度查詢的匹配必須出現在第N的位置 |
spanNearQuery | 接受多個跨度查詢的匹配必須在指定的距離,並可能在相同的順序 |
spanNotQuery | 包裝另一個跨度查詢,排除了任何文檔匹配查詢 |
spanOrQuery | 結合多個跨度查詢,返回文檔的匹配任何指定的查詢 |
spanWithinQuery | 和spanContainingQuery類似 |
spanContainingQuery | 這個查詢內部會有多個子查詢,但是會設定某個子查詢優先級更高,作用更大,通過關鍵字little和big來指定 |
spanMultiTermQueryBuilder | 包裝了 term, range, prefix, wildcard, regexp,或 fuzzy查詢 |
spanTermQuery | 和spanQuery類似,同時可以做爲spanQuery的子句 |
初始化elasticsearch客戶端
Settings settings = Settings.builder()
.put("cluster.name", "my-application")// 集羣名稱yml配置
.put("client.transport.ping_timeout", "60s")// 超時時間
.put("client.transport.sniff", false)//是否開啓自動發現,非局域網關閉
.put("client.transport.ignore_cluster_name", false).build();
try {
client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(InetAddress.getByName(ip), 9300));
} catch (UnknownHostException e) {
e.printStackTrace();
}
elasticsearch常使用的用法
package com.xue;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.Map;
/**
* Created by xuehan on 2018/12/10.
*/
/**1. index的操作*/
public class ElSearch {
private Client client = null;
@Before
public void init(){
ESTest esTest = new ESTest();
client = esTest.getClient();
}
/**2. mapping映射操作*/
@Test
public void testCreateIndex() {
IndicesAdminClient indices = client.admin().indices();
String esIndex = "myindex";
// 判斷inedx是否存在
IndicesExistsResponse indicesExistsResponse = indices.prepareExists(esIndex).get();
if (indicesExistsResponse.isExists()) {
// 存在時先刪除index
indices.prepareDelete(esIndex).get();
}
// 創建前校驗(index不存在)
indicesExistsResponse = indices.prepareExists(esIndex).get();
Assert.assertFalse(indicesExistsResponse.isExists());
// 開始創建index
indices.prepareCreate(esIndex).get();
// 創建後校驗(index存在)
indicesExistsResponse = indices.prepareExists(esIndex).get();
Assert.assertTrue(indicesExistsResponse.isExists());
}
@Test
public void testMapping() throws IOException {
String esIndex = "testMapping";
IndicesAdminClient indices = client.admin().indices();
// 判斷inedx是否存在
IndicesExistsResponse indicesExistsResponse = indices.prepareExists(esIndex).get();
if (indicesExistsResponse.isExists()) {
// 存在時先刪除index
indices.prepareDelete(esIndex).get();
}
// 創建新的index
indices.prepareCreate(esIndex).get();
// 執行前判斷(mapping不存在)
String esType = "esType";
GetMappingsResponse getMappingsResponse = indices.prepareGetMappings(esIndex).setTypes(esType).get();
Assert.assertTrue(getMappingsResponse.mappings().isEmpty());
// 執行mapping
PutMappingRequestBuilder builder = indices.preparePutMapping(esIndex).setType(esType);
String mappingFile = getClass().getResource("/").getPath() + "search/lg_line_mapping.json";
String mappingSource = FileUtils.readFileToString(new File(mappingFile));
builder.setSource(mappingSource).get();
// 執行後判斷(mapping存在)
getMappingsResponse = indices.prepareGetMappings(esIndex).setTypes(esType).get();
Assert.assertFalse(getMappingsResponse.mappings().isEmpty());
}
@Test
public void testIndexing() {
String esType = "esType";
String esIndex = "myindex";
// 不管有沒有,先刪除數據
client.prepareDelete(esIndex, esType, "1").execute();
// 執行前判斷(數據不存在)
GetResponse response = client.prepareGet(esIndex, esType, "1").get();
Assert.assertNull(response.getSourceAsString());
// 插入數據
LineIndexingVO lineIndexingVO = new LineIndexingVO();
lineIndexingVO.setId(1L);
lineIndexingVO.setLineNo("LM2017041913250001");
lineIndexingVO.setGlobal_ana_ch("浙江,杭州,冬瓜,西瓜,地鐵,番茄泡");
String lineIndexingVOStr = JSONObject.toJSONString(lineIndexingVO);
Map<String, Object> map = JSONObject.parseObject(lineIndexingVOStr, Map.class);
client.prepareIndex(esIndex, esType, "1").setSource(map).execute();
// 執行後判斷(數據存在)
response = client.prepareGet(esIndex, esType, "1").get();
Assert.assertNotNull(response.getSourceAsString());
}
/**4. matchQuery查詢**/
/**
* 關鍵詞匹配,global_ana_ch是一個分詞的字段可以進行搜索匹配
*/
@Test
public void testMatchQuery() {
String esType = "esType";
String esIndex = "myindex";
// 插入數據
LineIndexingVO lineIndexingVO = new LineIndexingVO();
lineIndexingVO.setId(1L);
lineIndexingVO.setLineNo("LM2017041913250001");
lineIndexingVO.setGlobal_ana_ch("浙江,杭州,冬瓜,西瓜,地鐵,番茄泡");
String lineIndexingVOStr = JSONObject.toJSONString(lineIndexingVO);
Map<String, Object> map = JSONObject.parseObject(lineIndexingVOStr, Map.class);
client.prepareIndex(esIndex, esType, "1").setSource(map).execute();
// 執行matchQuery查詢
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(esIndex).setTypes(esType);
MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("global_ana_ch", "杭州西湖");
SearchResponse response = searchRequestBuilder.setQuery(matchQuery).setFrom(0).setSize(1).get();
Assert.assertEquals(1, response.getHits().getTotalHits());
}
/**
* 過濾查詢
*/
@Test
public void testTerm() {
String esType = "esType";
String esIndex = "myindex";
// 插入數據
LineIndexingVO lineIndexingVO = new LineIndexingVO();
lineIndexingVO.setId(1L);
lineIndexingVO.setLineNo("LM2017041913250001");
lineIndexingVO.setGlobal_ana_ch("浙江,杭州,冬瓜,西瓜,地鐵,番茄泡");
String lineIndexingVOStr = JSONObject.toJSONString(lineIndexingVO);
Map<String, Object> map = JSONObject.parseObject(lineIndexingVOStr, Map.class);
client.prepareIndex(esIndex, esType, "1").setSource(map).execute();
// 執行term查詢,相當於select * from lg_line where id=1 and lineNo="LM2017041913250001"
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(esIndex).setTypes(esType);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("lineNo", "LM2017041913250001"));
// boolQueryBuilder.must(QueryBuilders.termQuery("id", 1));
SearchResponse response = searchRequestBuilder.setQuery(boolQueryBuilder).get();
Assert.assertEquals(1, response.getHits().getTotalHits());
// 執行term查詢,相當於select * from lg_line where id=1 and lineNo="LM2017041913250001" and lineNo!="LM2017041913250001"
boolQueryBuilder.mustNot(QueryBuilders.termQuery("lineNo", "LM2017041913250001"));
response = searchRequestBuilder.setQuery(boolQueryBuilder).setFrom(0).setSize(1).get();
Assert.assertEquals(0, response.getHits().getTotalHits());
}
/**
* 排序測試
*/
@Test
public void testOrder() {
String esType = "esType";
String esIndex = "myindex";
// 插入數據
LineIndexingVO lineIndexingVO = new LineIndexingVO();
lineIndexingVO.setId(1L);
lineIndexingVO.setLineNo("LM2017041913250001");
lineIndexingVO.setGlobal_ana_ch("浙江,杭州,冬瓜,西瓜,地鐵,番茄泡");
String lineIndexingVOStr = JSONObject.toJSONString(lineIndexingVO);
Map<String, Object> map = JSONObject.parseObject(lineIndexingVOStr, Map.class);
client.prepareIndex(esIndex, esType, "1").setSource(map).execute();
// 第二條數據比第一條少了“杭州”
lineIndexingVO = new LineIndexingVO();
lineIndexingVO.setId(2L);
lineIndexingVO.setLineNo("LM2017041913250002");
lineIndexingVO.setGlobal_ana_ch("浙江,冬瓜,西瓜,地鐵,番茄泡");
String lineIndexingVOStr1 = JSONObject.toJSONString(lineIndexingVO);
Map<String, Object> map1 = JSONObject.parseObject(lineIndexingVOStr1, Map.class);
client.prepareIndex(esIndex, esType, "2").setSource(map1).execute();
MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("global_ana_ch", "浙江杭州");
// 根據匹配度倒序排列,匹配度高的排在前面
SearchResponse response = client.prepareSearch(esIndex).setTypes(esType).setQuery(matchQuery).setFrom(0).setSize(2)
.addSort("_score", SortOrder.DESC).get();
Assert.assertEquals("1", response.getHits().iterator().next().getId());
// 根據匹配度順序排列,匹配度低的排在前面
response = client.prepareSearch(esIndex).setTypes(esType).setQuery(matchQuery).setFrom(0).setSize(2).addSort("_score", SortOrder.ASC).get();
Assert.assertEquals("2", response.getHits().iterator().next().getId());
}
/**7.統計查詢**/
@Test
public void testAggs() {
String esType = "esType1";
String esIndex = "aggs";
// 插入數據
LineIndexingVO lineIndexingVO = new LineIndexingVO();
lineIndexingVO.setId(1L);
lineIndexingVO.setLineType("1");
lineIndexingVO.setGlobal_ana_ch("浙江,杭州,冬瓜,西瓜,地鐵,番茄泡");
String lineIndexingVOStr1 = JSONObject.toJSONString(lineIndexingVO);
Map<String, Object> map1 = JSONObject.parseObject(lineIndexingVOStr1, Map.class);
client.prepareIndex(esIndex, esType, "1").setSource(map1).execute();
lineIndexingVO = new LineIndexingVO();
lineIndexingVO.setId(2L);
lineIndexingVO.setLineType("1");
lineIndexingVO.setGlobal_ana_ch("浙江,冬瓜,西瓜,地鐵,番茄泡");
String lineIndexingVOStr2 = JSONObject.toJSONString(lineIndexingVO);
Map<String, Object> map2 = JSONObject.parseObject(lineIndexingVOStr2, Map.class);
client.prepareIndex(esIndex, esType, "2").setSource(map2).execute();
lineIndexingVO = new LineIndexingVO();
lineIndexingVO.setId(3L);
lineIndexingVO.setLineType("2");
lineIndexingVO.setGlobal_ana_ch("浙江,冬瓜,西瓜,地鐵,番茄泡");
String lineIndexingVOStr3 = JSONObject.toJSONString(lineIndexingVO);
Map<String, Object> map3 = JSONObject.parseObject(lineIndexingVOStr3, Map.class);
client.prepareIndex(esIndex, esType, "3").setSource(map3).execute();
/**
* 需要設置索引
* {
"properties": {
"lineType": {
"type": "text",
"fielddata": true
}
}
}
http://47.105.74.94:9200/aggs/_mapping/esType1
*/
// 根據lineType進行分類統計,type=1的有2條,type=2的有1條
TermsAggregationBuilder termsBuilder = AggregationBuilders.terms("by_lineType").field("lineType");
SearchResponse response = client.prepareSearch(esIndex).setTypes(esType).addAggregation(termsBuilder).setSize(10).get();
StringTerms aggregation = response.getAggregations().get("by_lineType");
Assert.assertEquals(2, aggregation.getBucketByKey("1").getDocCount());
Assert.assertEquals(1, aggregation.getBucketByKey("2").getDocCount());
}
class LineIndexingVO{
private double id;
private String lineNo;
private String lineType;
private String global_ana_ch;
public double getId() {
return id;
}
public void setId(double id) {
this.id = id;
}
public String getLineNo() {
return lineNo;
}
public void setLineNo(String lineNo) {
this.lineNo = lineNo;
}
public String getGlobal_ana_ch() {
return global_ana_ch;
}
public void setGlobal_ana_ch(String global_ana_ch) {
this.global_ana_ch = global_ana_ch;
}
public String getLineType() {
return lineType;
}
public void setLineType(String lineType) {
this.lineType = lineType;
}
}
}