Elasticsearch 接口介绍和java API实例

说明

  • 本博客是继上篇的扩展,整理介绍操作和官方java API功能,并创建实例java maven项目,记性实际操作。

http操作

接口说明

  • 官方接口语法curl ‐X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' ‐d '<BODY>'
参数 解释
VERB 适当的HTTP方法即:GET、POST、PUT、HEAD、DELTETE
PROTOCOL http或https,当前官方为http
HOST 任意节点的主机名,分布式安装也是任意节点
PORT http服务端口,默认9200
PATH API的终端路径,如_count返回集群中文档数量
QUERY——STRING 任意可选的查询字符串参数
BODY 一个JSON格式的请求体,非必须

创建索引库并mapping

  • 请求put http://172.0.0.1:9200/hello 创建hello索引
  • 请求体:
    • article:type类型;相当于这个索引库中有张表叫做article下面定义的这张表中的字段的定义,字段默认为不索引的;
    • analyzer:分词器使用标准分词器
    {
          
          
        "mappings": {
          
          
            "article": {
          
          
                "properties": {
          
          
                    "id": {
          
          
                        "type": "long",
                        "store": true,
                        "index": "not_analyzed"
                    },
                    "title": {
          
          
                        "type": "text",
                        "store": true,
                        "index": "analyzed",
                        "analyzer": "standard"
                    },
                    "content": {
          
          
                        "type": "text",
                        "store": true,
                        "index": "analyzed",
                        "analyzer": "standard"
                    }
                }
            }
        }
    }
    

创建索引库再mapping

  • 创建索引库put http://172.0.0.1:9200/hello2
  • 添加mapping
    • 请求PUT http://127.0.0.1:9200/hello2/article/_mapping
    • 请求体:
    {
          
          
       "article": {
          
          
              "properties": {
          
          
                  "id": {
          
          
                      "type": "long",
                      "store": true,
                      "index": "not_analyzed"
                  },
                  "title": {
          
          
                      "type": "text",
                      "store": true,
                      "index": "analyzed",
                      "analyzer": "standard"
                  },
                  "content": {
          
          
                      "type": "text",
                      "store": true,
                      "index": "analyzed",
                      "analyzer": "standard"
                  }
              }
          }
    }
    

删除索引

  • 请求DELETE http://127.0.0.1:9200/hello2

创建文档

  • 请求POST http://127.0.0.1:9200/hello/article/1
  • 请求体,一般_id和id值相同
{
    
    
    "id": 1,
    "title": "ElasticSearch是一个基于Lucene的搜索服务器",
    "content": "它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。"
}

修改文档

  • 请求POST http://127.0.0.1:9200/hello/article/1
  • 请求体
{
    
    
    "id": 1,
    "title": "第一次修改ElasticSearch是一个基于Lucene的搜索服务器",
    "content": "第一次修改它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。"
}

删除文档

  • 请求DELETE http://127.0.0.1:9200/hello/article/2

查看文档

  • 查看文档有三种方式
    • 根据id查看
      • 请求GET http://127.0.0.1:9200/hello/article/1
    • 更加关键词查看
      • 请求POST http://127.0.0.1:9200/hello/article/_search
      • 请求体
      {
              
              
      "query": {
              
              
          "term": {
              
              
              "title": "搜"
          }
        }
      }
      
    • 更加输入内容分词再查看
      • 请求POST http://127.0.0.1:9200/hello/article/_search
      • 请求体
      {
              
              
      "query": {
              
              
          "query_string": {
              
              
              "default_field": "title",
              "query": "搜索服务器"
          }
        }
      }
      

官方java API文档

  • 以下都是我从官方一个个阅读整理的,全部基于RestHightLevelClient,TransportClient 8版本后删除。

文档详情

java API代码

查询类说明

  • RangeQueryBuilder 范围查找 gt:大于 lt:小于 gte:大于等于 lte:小于等于
  • WildcardQueryBuilder 模糊查询 使用*表示任意字符
  • TermQueryBuilder 精确查询
  • BoolQueryBuilder 布尔类型查询 用于多条件的拼接(可用使用以下三个方法进行拼接条件)
  • must 必须的 文档必须满足匹配条件
  • must_not 文档必须不匹配条件
  • should 或者 文档只要满足一个或多个条件

导包

<dependency>
  <groupId>org.elasticsearch</groupId>
  <artifactId>elasticsearch</artifactId>
  <version>7.3.0</version>
</dependency>

<dependency>
  <groupId>org.elasticsearch.client</groupId>
  <artifactId>elasticsearch-rest-high-level-client</artifactId>
  <version>7.3.0</version>
</dependency>

java工具类

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.http.HttpHost;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import lombok.extern.slf4j.Slf4j;


@Slf4j //使用了lombok,可以用手动引入private static final Logger log = LoggerFactory.getLogger(ESRestUtil.class);
public final class ESRestUtil {
    
    
	 
	    private RestHighLevelClient client;
	    
	    
	    public ESRestUtil() {
    
    
	        RestHighLevelClient client = new RestHighLevelClient(
	                RestClient.builder(
	                        //集群节点
//	                        new HttpHost("localhost", 9200, "http"),
	                        new HttpHost("localhost", 9200, "http")));
	        this.client = client;
	    }
	    
	    /**
	     * 关闭连接
	     */
	    public void shutdown(){
    
    
	        if(client!=null){
    
    
	            try {
    
    
	                client.close();
	            } catch (IOException e) {
    
    
	                e.printStackTrace();
	            }
	        }
	    }
	    
	    /**
	     * 创建index
	     * @param index 创建index
	     * @param numberShared 分片数
	     * @param numberReplicas 备份数
	     * @return
	     */
	    public boolean createIndex(String index,int numberShared,int numberReplicas) {
    
    
	    	CreateIndexRequest request = new CreateIndexRequest(index);
	    	
	    	//设置分片和备份数
	    	request.settings(Settings.builder() 
	    		    .put("index.number_of_shards", numberShared)
	    		    .put("index.number_of_replicas", numberReplicas)
	    		);
	    	
	    	//索引别名
	    	request.alias(new Alias(index+"_alias").filter(QueryBuilders.termQuery("user", "kimchy"))); 
	    	
	    	try {
    
    
				 client.indices().create(request, RequestOptions.DEFAULT);
			} catch (IOException e) {
    
    
				log.error(e.toString(),e);
				return false;
			}
	    	return true;
	    	
	    }
	    
	    //TODO 创建索引和规则
	    
	    /**
	     * 添加数据和修改
	     * 文档地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.10/java-rest-high-document-index.html
	     * @throws IOException
	     */
	    public boolean  addDataOrUpload(String index,String id,String jsonString)  {
    
    
	    	//指定索引
	    	IndexRequest request = new IndexRequest(index);
	    	//指定id
	    	request.id(id); 
	    	
	    	//添加的数据 文档
	    	request.source(jsonString, XContentType.JSON);
	    	
	    	//同步执行
	    	IndexResponse indexResponse;
			try {
    
    
				indexResponse = client.index(request, RequestOptions.DEFAULT);
			} catch (IOException e) {
    
    
				log.error("添加数据失败"+e.toString(),e);
				return false;
			}
	    	
	    	if(indexResponse.getResult()==DocWriteResponse.Result.CREATED) {
    
    
	    		log.info("First Create");
	    	}else if(indexResponse.getResult() ==DocWriteResponse.Result.UPDATED ) {
    
    
	    		log.info("Data Update");
	    	}
	    	
	    	return true;
	    	//异步添加
//	    	ActionListener<IndexResponse> listener = new ActionListener<IndexResponse>() {
    
    
//	    	    @Override
//	    	    public void onResponse(IndexResponse indexResponse) {
    
    
//	    	        
//	    	    }
//
//	    	    @Override
//	    	    public void onFailure(Exception e) {
    
    
//	    	        
//	    	    }
//	    	};
//	    	
//	    	client.indexAsync(request, RequestOptions.DEFAULT, listener);
	    }
	    
	 
	    /**
	     * 获取指定index和id的 数据
	     * @param index
	     * @param id
	     * @return
	     */
	    public Map<String, Object> getStringById(String index,String id){
    
    
	    	log.info("Search Index:{}  And Id:{}",index,id);
	        GetRequest getRequest = new GetRequest(index,id);  //index 和id
	        GetResponse response = null;
	        try {
    
    
	            response = this.client.get(getRequest, RequestOptions.DEFAULT);
	        } catch (IOException e) {
    
    
	            e.printStackTrace();
	        }
	        
	        //按字段Key获取对应的值
	        //DocumentField field = response.getField("content");
	        //获取全部的map,除了正常的值之外,会存在key是@version和@timestamp的值
	        Map<String, Object> source =  response.getSource();
	        
	        log.info("Result Is:"+JsonUtil.toJson(source));
	       return source;
	    }
	 
	    /**
	     * 根据指定的内容,模糊查询或精确查询所有Doc。
	     * @param content
	     * @return
	     */
	    public List<Map<String,Object>> getArticle(String index,String key,String content){
    
    
//	        QueryBuilder qb= QueryBuilders.boolQuery().must(QueryBuilders.termQuery("title","JAVA开发工程师")).must(QueryBuilders.termQuery("age",30)) ;
//	        //精确查询
	        QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(key, content);
//	        //模糊查询
//	        QueryBuilder matchQueryBuilder = QueryBuilders.matchPhraseQuery("content", content);
	        
	        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//	        sourceBuilder.query(QueryBuilders.termQuery("content", content));
	        sourceBuilder.query(matchQueryBuilder);
	        sourceBuilder.from(0);
	        sourceBuilder.size(10);
	        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
	        
	        SearchRequest searchRequest = new SearchRequest();
	        searchRequest.indices(index);
	        searchRequest.source(sourceBuilder);
	        SearchResponse searchResponse;
	        List<Map<String,Object>> list = new ArrayList<>();
	
	        try {
    
    
	            searchResponse = this.client.search(searchRequest,RequestOptions.DEFAULT);
	            SearchHits searchHits =  searchResponse.getHits();
	            for(SearchHit hit:searchHits.getHits()){
    
    
	                System.out.println( hit.getSourceAsString());
	                list.add(hit.getSourceAsMap());
	            }
	        } catch (IOException e) {
    
    
	            e.printStackTrace();
	        }

	        return list;
	    }
	    
	    /**
	     * 模糊查询
	     * @param index
	     * @param key
	     * @param value
	     * @return
	     */
	    public SearchHits search(String index,String key,String value){
    
    
	        QueryBuilder matchQueryBuilder = QueryBuilders.matchPhraseQuery(key, value);
	        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
	        
//	        sourceBuilder.query(QueryBuilders.termQuery("content", content));
	        sourceBuilder.query(matchQueryBuilder);
	        sourceBuilder.from(0);
	        sourceBuilder.size(100);
	        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
	        SearchRequest searchRequest = new SearchRequest();
	        searchRequest.indices(index);
	        searchRequest.source(sourceBuilder);
	        SearchResponse searchResponse;
	        List<Map<String,Object>> list = new ArrayList<>();
	        SearchHits searchHits = null;
	        try {
    
    
	            searchResponse = this.client.search(searchRequest,RequestOptions.DEFAULT);
	            searchHits =  searchResponse.getHits();
	            for(SearchHit hit:searchHits.getHits()){
    
    
	                System.out.println( hit.getSourceAsString());
	                list.add(hit.getSourceAsMap());
	            }
	        } catch (IOException e) {
    
    
	            e.printStackTrace();
	        }
	        return searchHits;
	    }
	 
	    /**
	     * 删除数据
	     * @param titleName
	     * @return
	     */
	    public long deleteArticle(String titleName){
    
    
	        long deleteNum = 0l;
	 
	        SearchHits searchHits = search("article-2019.08.08.03","title",titleName);
	        System.out.println("Exxcute Start" );
	        deleteCommon(searchHits);
	        //deleteAsync(searchHits);
	        System.out.println("Exxcute Done" );
	        return deleteNum;
	 
	    }
	 
	    /**
	     * 删除数据
	     * @param index
	     * @param id
	     */
	    public boolean deleteData(String index,String id) {
    
    
	    	DeleteRequest deleteRequest= new DeleteRequest(index,id);
	    	try {
    
    
                DeleteResponse deleteResponse = this.client.delete(deleteRequest,RequestOptions.DEFAULT);
                System.out.println("Delete Done【"+deleteResponse.getId()+"】,Status:【" + deleteResponse.status() + "】");
                return true;
            } catch (IOException e) {
    
    
            	log.error(e.toString(),e);
            }
	    	return false;
	    	
	    }
	    
	    /**
	     * 正常删除
	     * @param searchHits
	     */
	    private void deleteCommon (SearchHits searchHits){
    
    
	        DeleteRequest deleteRequest = new DeleteRequest();
	        for(SearchHit hit:searchHits.getHits()) {
    
    
	            deleteRequest = new DeleteRequest("article-2019.08.08.03",hit.getId());
	            try {
    
    
	                DeleteResponse deleteResponse = this.client.delete(deleteRequest,RequestOptions.DEFAULT);
	                System.out.println("Delete Done【"+deleteResponse.getId()+"】,Status:【" + deleteResponse.status() + "】");
	            } catch (IOException e) {
    
    
	                e.printStackTrace();
	            }
	        }
	    }
	 
	    /**
	     * 异步删除
	     * @param searchHits
	     */
	    @SuppressWarnings("unused")
		private void deleteAsync (SearchHits searchHits) {
    
    
	        DeleteRequest deleteRequest = new DeleteRequest();
	        for(SearchHit hit:searchHits.getHits()){
    
    
	            deleteRequest = new DeleteRequest("article-2019.08.08.03",hit.getId());
	 
	 
	            //异步删除
	            this.client.deleteAsync(deleteRequest, RequestOptions.DEFAULT, new ActionListener<DeleteResponse>() {
    
    
	                @Override
	                public void onResponse(DeleteResponse deleteResponse) {
    
    
	                    RestStatus restStatus = deleteResponse.status();
	                    int status = restStatus.getStatus();
	                    deleteResponse.getId();
	                    System.out.println("Delete Done【"+deleteResponse.getId()+"】,Status:【" + status + "】");
	                }
	                @Override
	                public void onFailure(Exception e) {
    
    
	                    e.printStackTrace();
	                    System.out.println("ERROR  " + hit.getId());
	                }
	            });
	        }
	 
	    }

}

总结

  • 官方java文档中,所有API都有两种形式,同步和异步,系统执行效率要求高的可考虑异步接口,同样业务流程随之增大。
  • 说点废话,有用共勉,无用忽略。
    • 程序员个人成长,第一步掌握一门编程语言,掌握的标准是,能用该语言完成任何需求,不考虑执行效率。第二步,实现基础上优化代码,大幅提升效率。第三步,考虑功能分析和架构、功能设计,评估不同编程语言的特性和技术可控性、扩展性,能为项目搭建和开发提供有效的技术架构和流程方案。

猜你喜欢

转载自blog.csdn.net/qq_22973811/article/details/114686943