詳解spring中使用Elasticsearch的代碼實(shí)現(xiàn)
在使用Elasticsearch之前,先給大家聊一點(diǎn)干貨。
1. ES和solr都是作為全文搜索引擎出現(xiàn)的。都是基于Lucene的搜索服務(wù)器。
2. ES不是可靠的存儲(chǔ)系統(tǒng),不是數(shù)據(jù)庫,它有丟數(shù)據(jù)的風(fēng)險(xiǎn)。
3. ES不是實(shí)時(shí)系統(tǒng),數(shù)據(jù)寫入成功只是trans log成功(類似于MySQL的bin log),寫入成功后立刻查詢查不到是正常的。因?yàn)閿?shù)據(jù)此刻可能還在內(nèi)存里而不是進(jìn)入存儲(chǔ)引擎里。同理,刪除一條數(shù)據(jù)后也不是馬上消失。寫入何時(shí)可查詢?ES內(nèi)部有一個(gè)后臺(tái)線程,定時(shí)將內(nèi)存中的一批數(shù)據(jù)寫入到存儲(chǔ)引擎,此后數(shù)據(jù)可見。默認(rèn)后臺(tái)線程一秒運(yùn)行一次。該線程運(yùn)行的越頻繁,寫入性能越低。運(yùn)行的頻率越低,寫入的性能越高(不會(huì)無限高)。
4. 目前已知的單ES集群可以存儲(chǔ)PB級(jí)別的數(shù)據(jù),不過這個(gè)就非常費(fèi)勁了。TB級(jí)別數(shù)據(jù)沒壓力。
5. 如果使用ES官方提供的jar包訪問,需要JDK1.7及以上。
6. 使用對(duì)應(yīng)的版本訪問ES server。如果ES server端的版本是1.7,那么請使用ES 1.7的client。如果ES server是2.1,請使用2.1的client。
7. ES索引存在Linux服務(wù)器的文件系統(tǒng)之上(背后是文件系統(tǒng),不是類似于HDFS的分布式文件系統(tǒng))
8. ES Java client是線程安全的,全局構(gòu)建一個(gè)即可滿足讀寫需求,不要每次都創(chuàng)建ES client。每次訪問ES都構(gòu)建新的es client即會(huì)拋出次異常。
9. 非常不建議使用ES的動(dòng)態(tài)識(shí)別和創(chuàng)建的機(jī)制,因?yàn)楹芏嗲闆r下這并非你所需要。推薦的做法是在寫數(shù)據(jù)之前仔細(xì)的創(chuàng)建mapping。
10. 強(qiáng)烈不建議在ES中使用深分頁。可能會(huì)導(dǎo)致集群不可用。
11. ES是靜態(tài)分片,一旦分片數(shù)在創(chuàng)建索引時(shí)確定那么后繼不能修改。
12. ES里提供了type,很多人以為type是物理表,一個(gè)type的數(shù)據(jù)是獨(dú)立存儲(chǔ)的;但是在ES內(nèi)部并不是這樣,type在ES內(nèi)部僅僅是一個(gè)字段。所以在很多數(shù)據(jù)能分為獨(dú)立index的情況下,不要放到一個(gè)index里用type去分。只有嵌套類和父子類的情況下使用type才是合理的。
13. ES并不提供原生的中文分詞的能力。有第三方的中文分詞的插件,比如ik等。Ik是個(gè)toy分詞器,有嚴(yán)肅的分詞需求的話,請?jiān)谑褂肊S之前使用獨(dú)立的分詞器分好詞后向ES寫入。
14. ES中的index,首先會(huì)進(jìn)行分片,每一個(gè)分片數(shù)據(jù)一般都會(huì)有自己的副本數(shù)據(jù),ES分配分片的策略會(huì)保證同一個(gè)分片數(shù)據(jù)和自己的副本不會(huì)分配到同一個(gè)節(jié)點(diǎn)上。當(dāng)集群中的某一節(jié)點(diǎn)宕機(jī)后,ES的master在ping該節(jié)點(diǎn)時(shí)通過一定的策略會(huì)發(fā)現(xiàn)該節(jié)點(diǎn)不存活;會(huì)開啟ES的恢復(fù)過程
15. ES沒有update的能力。所有的update都是標(biāo)記刪除老文檔,然后重新insert一條新文檔。
好了,回歸正題。
首先:
增加我們的spring配置
<bean id="client" factory-bean="esClientBuilder" factory-method="init" destroy-method="close"/> <bean id="esClientBuilder" class="com.***.EsClientBuilder"> <property name="clusterName" value="集群名稱" /> <property name="nodeIpInfo" value="集群地址" /> </bean>
其次:
編寫我們的EsClientBuilder類初始化我們的ES參數(shù)
package ***; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; public class EsClientBuilder { private String clusterName; private String nodeIpInfo; private TransportClient client; public Client init(){ //設(shè)置集群的名字 Settings settings = Settings.settingsBuilder() .put("client.transport.sniff", false) .put("cluster.name", clusterName) .build(); //創(chuàng)建集群client并添加集群節(jié)點(diǎn)地址 client = TransportClient.builder().settings(settings).build(); Map<String, Integer> nodeMap = parseNodeIpInfo(); for (Map.Entry<String,Integer> entry : nodeMap.entrySet()){ try { client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(entry.getKey()), entry.getValue())); } catch (UnknownHostException e) { e.printStackTrace(); } } return client; } /** * 解析節(jié)點(diǎn)IP信息,多個(gè)節(jié)點(diǎn)用逗號(hào)隔開,IP和端口用冒號(hào)隔開 * * @return */ private Map<String, Integer> parseNodeIpInfo(){ String[] nodeIpInfoArr = nodeIpInfo.split(","); Map<String, Integer> map = new HashMap<String, Integer>(nodeIpInfoArr.length); for (String ipInfo : nodeIpInfoArr){ String[] ipInfoArr = ipInfo.split(":"); map.put(ipInfoArr[0], Integer.parseInt(ipInfoArr[1])); } return map; } public String getClusterName() { return clusterName; } public void setClusterName(String clusterName) { this.clusterName = clusterName; } public String getNodeIpInfo() { return nodeIpInfo; } public void setNodeIpInfo(String nodeIpInfo) { this.nodeIpInfo = nodeIpInfo; } }
最后:
下面我們就可以寫自己的service類了,此類就可以通過es的原生api來操作我們的es(這里我們展示的2.X版本的)
indexName相當(dāng)于數(shù)據(jù)庫名,typeName相當(dāng)于表名
請參考EsServiceImpl.Java文件
package ***; @Service("esService") public class EsServiceImpl{ @Autowired private Client client; /** * 用docId獲取document * @param indexName * @param typeName * @param docId */ private static void getWithId(String indexName, String typeName, String docId) { //get with id GetResponse gResponse = client.prepareGet(indexName, typeName, docId).execute().actionGet(); System.out.println(gResponse.getIndex()); System.out.println(gResponse.getType()); System.out.println(gResponse.getVersion()); System.out.println(gResponse.isExists()); Map<String, Object> results = gResponse.getSource(); if(results != null) { for(String key : results.keySet()) { Object field = results.get(key); System.out.println(key); System.out.println(field); } } } private static void indexWithBulk(String index, String type) { //指定索引名稱,type名稱和documentId(documentId可選,不設(shè)置則系統(tǒng)自動(dòng)生成)創(chuàng)建document IndexRequest ir1 = new IndexRequest(); String source1 = "{" + "\"user\":\"kimchy\"," + "\"price\":\"6.3\"," + "\"tid\":\"20001\"," + "\"message\":\"Elasticsearch\"" + "}"; ir1.index(index).type(type).id("100").source(source1); IndexRequest ir2 = new IndexRequest(); String source2 = "{" + "\"user\":\"kimchy2\"," + "\"price\":\"7.3\"," + "\"tid\":\"20002\"," + "\"message\":\"Elasticsearch\"" + "}"; ir2.index(index).type(type).id("102").source(source2); IndexRequest ir3 = new IndexRequest(); String source3 = "{" + "\"user\":\"kimchy3\"," + "\"price\":\"8.3\"," + "\"tid\":\"20003\"," + "\"message\":\"Elasticsearch\"" + "}"; ir3.index(index).type(type).id("103").source(source3); BulkResponse response = client.prepareBulk().add(ir1).add(ir2).add(ir3).execute().actionGet(); BulkItemResponse[] responses = response.getItems(); if(responses != null && responses.length > 0) { for(BulkItemResponse r : responses) { String i = r.getIndex(); String t = r.getType(); System.out.println(i+","+t); } } } private static void sumCountSearch(String indexName, String typeName, String sumField, String countField, String searchField, String searchValue) { SumBuilder sb = AggregationBuilders.sum("sumPrice").field(sumField); TermQueryBuilder tb = QueryBuilders.termQuery(searchField, searchValue); SearchResponse sResponse = client.prepareSearch(indexName).setTypes(typeName).setQuery(tb).addAggregation(sb).execute().actionGet(); Map<String, Aggregation> aggMap = sResponse.getAggregations().asMap(); if(aggMap != null && aggMap.size() > 0) { for(String key : aggMap.keySet()) { if("sumPrice".equals(key)) { Sum s = (Sum)aggMap.get(key); System.out.println(key + "," + s.getValue()); } else if("countTid".equals(key)) { StatsBuilder c = (StatsBuilder)aggMap.get(key); System.out.println(key + "," + c.toString()); } } } } private static void updateDoc(String indexName, String typeName, String id) throws IOException, InterruptedException, ExecutionException { UpdateRequest updateRequest = new UpdateRequest(); updateRequest.index(indexName); updateRequest.type(typeName); updateRequest.id(id); updateRequest.doc(jsonBuilder().startObject().field("gender", "male").endObject()); UpdateResponse resp = client.update(updateRequest).get(); resp.getClass(); } private static void scrollSearch(String indexName, String typeName, String... ids) { IdsQueryBuilder qb = QueryBuilders.idsQuery().addIds(ids); SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) .setSearchType(SearchType.SCAN) .setQuery(qb) .setScroll(new TimeValue(100)) .setSize(50) .execute() .actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); System.out.println(tShards+","+timeCost+","+sShards); while (true) { SearchHits hits = sResponse.getHits(); SearchHit[] hitArray = hits.getHits(); for(int i = 0; i < hitArray.length; i++) { SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for(String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } sResponse = client.prepareSearchScroll(sResponse.getScrollId()).setScroll(new TimeValue(100)).execute().actionGet(); if (sResponse.getHits().getHits().length == 0) { break; } } } private static void deleteDocuments(String string, String string2) { SearchResponse sResponse = client.prepareSearch(string) .setTypes(string2) .setSearchType(SearchType.QUERY_THEN_FETCH) .setQuery(QueryBuilders.matchAllQuery()) .setFrom(0).setSize(60) .execute() .actionGet(); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); List<String> ids = new ArrayList<String>(hitArray.length); for(int i = 0; i < count; i++) { System.out.println("=================================="); SearchHit hit = hitArray[i]; ids.add(hit.getId()); } for(String id : ids) { DeleteResponse response = client.prepareDelete(string, string2, id).execute().actionGet(); } } private static void dateRangeSearch(String indexName, String typeName, String termName, String from, String to) { // 構(gòu)建range query //2015-08-20 12:27:11 QueryBuilder qb = QueryBuilders.rangeQuery(termName).from(from).to(to); SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) // 設(shè)置search type // 常用search type用:query_then_fetch // query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) // 查詢的termName和termvalue .setQuery(qb) // 設(shè)置排序field .addSort(termName, SortOrder.DESC) // 設(shè)置分頁 .setFrom(0).setSize(60).execute().actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); System.out.println(tShards + "," + timeCost + "," + sShards); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for (int i = 0; i < count; i++) { SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for (String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } } private static void dateRangeSearch2(String indexName, String typeName, String termName, String from, String to) { // 構(gòu)建range query QueryBuilder qb = QueryBuilders.rangeQuery(termName).from(from).to(to); SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) // 設(shè)置search type // 常用search type用:query_then_fetch // query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) // 查詢的termName和termvalue .setQuery(qb) // 設(shè)置排序field .addSort(termName, SortOrder.DESC) // 設(shè)置分頁 .setFrom(0).setSize(60).execute().actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); System.out.println(tShards + "," + timeCost + "," + sShards); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for (int i = 0; i < count; i++) { SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for (String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } } private static void countWithQuery(String indexName, String typeName, String termName, String termValue, String sortField, String highlightField) { //search result get source CountResponse cResponse = client.prepareCount(indexName) .setTypes(typeName) .setQuery(QueryBuilders.termQuery(termName, termValue)) .execute() .actionGet(); int tShards = cResponse.getTotalShards(); int sShards = cResponse.getSuccessfulShards(); System.out.println(tShards+","+sShards); long count = cResponse.getCount(); } private static void rangeSearchWithOtherSearch(String indexName, String typeName, String termName, String min, String max, String termQueryField) { // 構(gòu)建range query QueryBuilder qb = QueryBuilders.rangeQuery(termName).from(min).to(max); TermQueryBuilder tb = QueryBuilders.termQuery(termName, termQueryField); BoolQueryBuilder bq = boolQuery().must(qb).must(tb); SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) // 設(shè)置search type // 常用search type用:query_then_fetch // query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) // 查詢的termName和termvalue .setQuery(bq) // 設(shè)置排序field .addSort(termName, SortOrder.DESC) // 設(shè)置分頁 .setFrom(0).setSize(60).execute().actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); System.out.println(tShards + "," + timeCost + "," + sShards); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for (int i = 0; i < count; i++) { SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for (String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } } private static void termRangeSearch(String indexName, String typeName, String termName, String min, String max, String highlightField) { QueryBuilder qb = QueryBuilders.rangeQuery(termName).from(min).to(max); SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) // 設(shè)置search type // 常用search type用:query_then_fetch // query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) // 查詢的termName和termvalue .setQuery(qb) // 設(shè)置排序field .addSort(termName, SortOrder.DESC) //設(shè)置高亮field .addHighlightedField(highlightField) // 設(shè)置分頁 .setFrom(0).setSize(60).execute().actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); System.out.println(tShards + "," + timeCost + "," + sShards); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for (int i = 0; i < count; i++) { SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for (String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } } private static void sumOneField(String indexName, String typeName, String fieldName) { SumBuilder sb = AggregationBuilders.sum("sum").field(fieldName); //search result get source SearchResponse sResponse = client.prepareSearch(indexName).setTypes(typeName).addAggregation(sb).execute().actionGet(); Map<String, Aggregation> aggMap = sResponse.getAggregations().asMap(); if(aggMap != null && aggMap.size() > 0) { for(String key : aggMap.keySet()) { Sum s = (Sum)aggMap.get(key); System.out.println(s.getValue()); } } } private static void searchWithTermQueryAndRetureSpecifiedFields(String indexName, String typeName, String termName,String termValue, String sortField, String highlightField,String... fields) { SearchRequestBuilder sb = client.prepareSearch(indexName) .setTypes(typeName) // 設(shè)置search type // 常用search type用:query_then_fetch // query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) // 查詢的termName和termvalue .setQuery(QueryBuilders.termQuery(termName, termValue)) // 設(shè)置排序field .addSort(sortField, SortOrder.DESC) // 設(shè)置高亮field .addHighlightedField(highlightField) // 設(shè)置分頁 .setFrom(0).setSize(60); for (String field : fields) { sb.addField(field); } SearchResponse sResponse = sb.execute().actionGet(); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for (int i = 0; i < count; i++) { SearchHit hit = hitArray[i]; Map<String, SearchHitField> fm = hit.getFields(); for (String key : fm.keySet()) { SearchHitField f = fm.get(key); System.out.println(f.getName()); System.out.println(f.getValue()); } } } private static void searchWithIds(String indexName, String typeName, String sortField, String highlightField, String... ids) { IdsQueryBuilder qb = QueryBuilders.idsQuery().addIds(ids); SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) //設(shè)置search type //常用search type用:query_then_fetch //query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) //查詢的termName和termvalue .setQuery(qb) //設(shè)置排序field .addSort(sortField, SortOrder.DESC) //設(shè)置高亮field .addHighlightedField(highlightField) //設(shè)置分頁 .setFrom(0).setSize(60) .execute() .actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); System.out.println(tShards+","+timeCost+","+sShards); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for(int i = 0; i < count; i++) { SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for(String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } } /** * 在index:indexName, type:typeName中做通配符查詢 * @param indexName * @param typeName * @param termName * @param termValue * @param sortField * @param highlightField */ private static void wildcardSearch(String indexName, String typeName, String termName, String termValue, String sortField, String highlightField) { QueryBuilder qb = QueryBuilders.wildcardQuery(termName, termValue); SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) //設(shè)置search type //常用search type用:query_then_fetch //query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) //查詢的termName和termvalue .setQuery(qb) //設(shè)置排序field // .addSort(sortField, SortOrder.DESC) //設(shè)置高亮field // .addHighlightedField(highlightField) //設(shè)置分頁 .setFrom(0).setSize(60) .execute() .actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); System.out.println(tShards+","+timeCost+","+sShards); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for(int i = 0; i < count; i++) { SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for(String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } } /** * 在index:indexName, type:typeName中做模糊查詢 * @param indexName * @param typeName * @param termName * @param termValue * @param sortField * @param highlightField */ private static void fuzzySearch(String indexName, String typeName, String termName, String termValue, String sortField, String highlightField) { QueryBuilder qb = QueryBuilders.fuzzyQuery(termName, termValue); SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) //設(shè)置search type //常用search type用:query_then_fetch //query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) //查詢的termName和termvalue .setQuery(qb) //設(shè)置排序field .addSort(sortField, SortOrder.DESC) //設(shè)置高亮field .addHighlightedField(highlightField) //設(shè)置分頁 .setFrom(0).setSize(60) .execute() .actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); System.out.println(tShards+","+timeCost+","+sShards); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for(int i = 0; i < count; i++) { SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for(String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } } /** * 在index:indexName, type:typeName中做區(qū)間查詢 * @param indexName * @param typeName * @param termName * @param min * @param max * @param highlightField */ private static void numericRangeSearch(String indexName, String typeName, String termName, double min, double max, String highlightField) { // 構(gòu)建range query QueryBuilder qb = QueryBuilders.rangeQuery(termName).from(min).to(max); SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) // 設(shè)置search type // 常用search type用:query_then_fetch // query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) // 查詢的termName和termvalue .setQuery(qb) // 設(shè)置排序field .addSort(termName, SortOrder.DESC) //設(shè)置高亮field .addHighlightedField(highlightField) // 設(shè)置分頁 .setFrom(0).setSize(60).execute().actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); System.out.println(tShards + "," + timeCost + "," + sShards); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for (int i = 0; i < count; i++) { SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for (String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } } /** * 在索引indexName, type為typeName中查找兩個(gè)term:term1(termName1, termValue1)和term2(termName2, termValue2) * @param indexName * @param typeName * @param termName1 * @param termValue1 * @param termName2 * @param termValue2 * @param sortField * @param highlightField */ private static void searchWithBooleanQuery(String indexName, String typeName, String termName1, String termValue1, String termName2, String termValue2, String sortField, String highlightField) { //構(gòu)建boolean query BoolQueryBuilder bq = boolQuery().must(termQuery(termName1, termValue1)).must(termQuery(termName2, termValue2)); SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) //設(shè)置search type //常用search type用:query_then_fetch //query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) //查詢的termName和termvalue .setQuery(bq) //設(shè)置排序field .addSort(sortField, SortOrder.DESC) //設(shè)置高亮field .addHighlightedField(highlightField) //設(shè)置分頁 .setFrom(0).setSize(60) .execute() .actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); System.out.println(tShards+","+timeCost+","+sShards); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for(int i = 0; i < count; i++) { SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for(String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } } /** * 在索引indexName, type為typeName中查找term(termName, termValue) * @param indexName * @param typeName * @param termName * @param termValue * @param sortField * @param highlightField */ private static void searchWithTermQuery(String indexName, String typeName, String termName, String termValue, String sortField, String highlightField) { SearchResponse sResponse = client.prepareSearch(indexName) .setTypes(typeName) //設(shè)置search type //常用search type用:query_then_fetch //query_then_fetch是先查到相關(guān)結(jié)構(gòu),然后聚合不同node上的結(jié)果后排序 .setSearchType(SearchType.QUERY_THEN_FETCH) //查詢的termName和termvalue .setQuery(QueryBuilders.termQuery(termName, termValue)) //設(shè)置排序field // .addSort(sortField, SortOrder.DESC) //設(shè)置高亮field // .addHighlightedField(highlightField) //設(shè)置分頁 .setFrom(0).setSize(60) .execute() .actionGet(); int tShards = sResponse.getTotalShards(); long timeCost = sResponse.getTookInMillis(); int sShards = sResponse.getSuccessfulShards(); SearchHits hits = sResponse.getHits(); long count = hits.getTotalHits(); SearchHit[] hitArray = hits.getHits(); for(int i = 0; i < count; i++) { System.out.println("=================================="); SearchHit hit = hitArray[i]; Map<String, Object> fields = hit.getSource(); for(String key : fields.keySet()) { System.out.println(key); System.out.println(fields.get(key)); } } } /** * 用java的map構(gòu)建document */ private static void indexWithMap(String indexName, String typeName) { Map<String, Object> json = new HashMap<String, Object>(); //設(shè)置document的field json.put("user","kimchy2"); json.put("postDate",new Date()); json.put("price",6.4); json.put("message","Elasticsearch"); json.put("tid","10002"); json.put("endTime","2015-08-25 09:00:00"); //指定索引名稱,type名稱和documentId(documentId可選,不設(shè)置則系統(tǒng)自動(dòng)生成)創(chuàng)建document IndexResponse response = client.prepareIndex(indexName, typeName, "2").setSource(json).execute().actionGet(); //response中返回索引名稱,type名稱,doc的Id和版本信息 String index = response.getIndex(); String type = response.getType(); String id = response.getId(); long version = response.getVersion(); boolean created = response.isCreated(); System.out.println(index+","+type+","+id+","+version+","+created); } /** * 用java字符串創(chuàng)建document */ private static void indexWithStr(String indexName, String typeName) { //手工構(gòu)建json字符串 //該document包含user, postData和message三個(gè)field String json = "{" + "\"user\":\"kimchy\"," + "\"postDate\":\"2013-01-30\"," + "\"price\":\"6.3\"," + "\"tid\":\"10001\"," + "}"; //指定索引名稱,type名稱和documentId(documentId可選,不設(shè)置則系統(tǒng)自動(dòng)生成)創(chuàng)建document IndexResponse response = client.prepareIndex(indexName, typeName, "1") .setSource(json) .execute() .actionGet(); //response中返回索引名稱,type名稱,doc的Id和版本信息 String index = response.getIndex(); String type = response.getType(); String id = response.getId(); long version = response.getVersion(); boolean created = response.isCreated(); System.out.println(index+","+type+","+id+","+version+","+created); } private static void deleteDocWithId(String indexName, String typeName, String docId) { DeleteResponse dResponse = client.prepareDelete(indexName, typeName, docId).execute().actionGet(); String index = dResponse.getIndex(); String type = dResponse.getType(); String id = dResponse.getId(); long version = dResponse.getVersion(); System.out.println(index+","+type+","+id+","+version); } /** * 創(chuàng)建索引 * 注意:在生產(chǎn)環(huán)節(jié)中通知es集群的owner去創(chuàng)建index * @param client * @param indexName * @param documentType * @throws IOException */ private static void createIndex(String indexName, String documentType) throws IOException { final IndicesExistsResponse iRes = client.admin().indices().prepareExists(indexName).execute().actionGet(); if (iRes.isExists()) { client.admin().indices().prepareDelete(indexName).execute().actionGet(); } client.admin().indices().prepareCreate(indexName).setSettings(Settings.settingsBuilder().put("number_of_shards", 1).put("number_of_replicas", "0")).execute().actionGet(); XContentBuilder mapping = jsonBuilder() .startObject() .startObject(documentType) // .startObject("_routing").field("path","tid").field("required", "true").endObject() .startObject("_source").field("enabled", "true").endObject() .startObject("_all").field("enabled", "false").endObject() .startObject("properties") .startObject("user") .field("store", true) .field("type", "string") .field("index", "not_analyzed") .endObject() .startObject("message") .field("store", true) .field("type","string") .field("index", "analyzed") .field("analyzer", "standard") .endObject() .startObject("price") .field("store", true) .field("type", "float") .endObject() .startObject("nv1") .field("store", true) .field("type", "integer") .field("index", "no") .field("null_value", 0) .endObject() .startObject("nv2") .field("store", true) .field("type", "integer") .field("index", "not_analyzed") .field("null_value", 10) .endObject() .startObject("tid") .field("store", true) .field("type", "string") .field("index", "not_analyzed") .endObject() .startObject("endTime") .field("type", "date") .field("store", true) .field("index", "not_analyzed") .field("format", "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSSZ") .endObject() .startObject("date") .field("type", "date") .endObject() .endObject() .endObject() .endObject(); client.admin().indices() .preparePutMapping(indexName) .setType(documentType) .setSource(mapping) .execute().actionGet(); } }
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解spring-boot集成elasticsearch及其簡單應(yīng)用
- SpringBoot整合ElasticSearch實(shí)踐
- spring 操作elasticsearch查詢使用方法
- 詳解centos7虛擬機(jī)安裝elasticsearch5.0.x-安裝篇
- centos下root運(yùn)行Elasticsearch異常問題解決
- Elasticsearch.Net使用教程 MVC4圖書管理系統(tǒng)(2)
- Elasticsearch.Net使用入門教程(1)
- 基于Lucene的Java搜索服務(wù)器Elasticsearch安裝使用教程
- 安裝ElasticSearch搜索工具并配置Python驅(qū)動(dòng)的方法
- elasticsearch插件開發(fā)教程
相關(guān)文章
使用Java編寫控制JDBC連接、執(zhí)行及關(guān)閉的工具類
這篇文章主要介紹了如何使用Java來編寫控制JDBC連接、執(zhí)行及關(guān)閉的程序,包括一個(gè)針對(duì)各種數(shù)據(jù)庫通用的釋放資源的工具類的寫法,需要的朋友可以參考下2016-03-03SpringBoot項(xiàng)目中處理返回json的null值(springboot項(xiàng)目為例)
本文以spring boot項(xiàng)目為例給大家介紹SpringBoot項(xiàng)目中處理返回json的null值問題,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下2019-10-10IDEA中已配置阿里鏡像但maven無法下載jar包的問題及解決方法
這篇文章主要介紹了IDEA中已配置阿里鏡像但maven無法下載jar包的問題,本文給大家分享解決方法,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08Java裝飾器設(shè)計(jì)模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java裝飾器設(shè)計(jì)模式的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-05-05java Array和Arrays的區(qū)別總結(jié)
在本篇內(nèi)容里小編給大家整理的是一篇關(guān)于java Array和Arrays的區(qū)別總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2021-03-03SpringBoot使用knife4j進(jìn)行在線接口調(diào)試
這篇文章主要介紹了SpringBoot使用knife4j進(jìn)行在線接口調(diào)試,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09