es学习1

一、简单介绍

elasticsearch是一个基于Lucene的高扩展的分布式搜索服务器,支持开箱即用。

elasticsearch隐藏了Lucene的复杂性,对外提供Restful 接口来操作索引、搜索。

二、es和关系型数据库的几个概念的对比

数据库--->表--->行--->列

索引--->类型--->文档--->字段(映射)

三、es的使用步骤

es对外提供的http操作端口是9200

3.1 创建索引

向es服务器发送put请求,创建索库

put http://localhost:9200/索引库名称

3.2 创建映射

在索引库中每个文档都包括了一个或多个field,创建映射就是向索引库中创建field的过程

post请求创建映射

post http://localhost:9200/索引库名称/类型名称/_mapping

请求体中是映射的具体配置

{
	"properties": {
		"name": {
			"type": "text",
			"analyzer":"ik_max_word",
			"search_analyzer":"ik_smart"
		},
		"pic": {
			"type": "text",
			"index":false
		},
		"studymodel": {
			"type": "keyword"
		},
		"description":{
		    "type":"text",
		    "analyzer":"ik_max_word",
		    "search_analyzer":"ik_smart"
		}
	}
}

3.3 创建文档

Post http://localhost:9200/索引库名称/类型名/

请求体中是文档的内容的json格式,和给索引库配置的映射一致。

3.4 查询文档

使用DSL搜索进行查询

DSL(Domain Specific Language)是ES提出的基于json的搜索方式,在搜索时传入特定的json格式的数据来完成不 同的搜索需求 。

查询地址: post http://localhost:9200/_search

在请求体中设置用DSL设置查询条件

{
	"query": {
		"match_all": {}
	},
	"_source": ["name", "studymodel"]
}

四、使用es的java客户端

es官方推荐使用高级别的restclient,Java High Level REST Client

使用方式:

对应的依赖:

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

在spring容器中配置restclient对象,这个是es java客户端的核心对象:RestHighLevelClient

@Configuration
public class ElasticConfig {

    @Value("${esclient.elasticserach.hostlist}")
    private String host;

    /**
     * 创建高级别的客户端
     * @return
     */
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        //解析host配置信息
        HttpHost httpHost=new HttpHost(host.split(":")[0],Integer.parseInt(host.split(":")[1]));
        //创建RestHighLevelClient
        return new RestHighLevelClient(RestClient.builder(httpHost));
    }
}

常见方法的使用:创建索引,添加文档,查询文档


@RunWith(SpringRunner.class)
@SpringBootTest(classes = EsStudyApplication.class)
public class Test1 {

    @Autowired
    private RestHighLevelClient highLevelClient;

    @Test
    public void testCreateIndex() throws IOException {
        //创建索引请求对象
        CreateIndexRequest createIndexRequest=new CreateIndexRequest("index_java");
        //创建索引操作客户端
        IndicesClient indices = highLevelClient.indices();
        //发起请求,创建索引
        CreateIndexResponse createIndexResponse = indices.create(createIndexRequest);
        boolean acknowledged = createIndexResponse.isAcknowledged();
        System.out.println("创建结果:"+acknowledged);
    }

    @Test
    public void testDeleteIndex() throws IOException {
        //创建删除索引请求对象
        DeleteIndexRequest deleteIndexRequest=new DeleteIndexRequest("index_java");
        //创建索引操作客户端,发起请求
        DeleteIndexResponse deleteIndexResponse = highLevelClient.indices().delete(deleteIndexRequest);
        System.out.println("删除结果:"+deleteIndexResponse.isAcknowledged());
    }

    @Test
    public void testAddDocument() throws IOException {
        Map<String,String> jsonMap=new HashMap<>();
        jsonMap.put("name","es");
        jsonMap.put("description","这是es学习第3天");
        jsonMap.put("studymodel","自学");
        jsonMap.put("pic","d:/123.jpg");

        //创建索引请求对象
        IndexRequest indexRequest=new IndexRequest("index_java","doc");
        indexRequest.id("7");//设置文档的id
        indexRequest.source(jsonMap);

        //请求添加索引
        IndexResponse addIndexResponse = highLevelClient.index(indexRequest);
        System.out.println(addIndexResponse.status());
        System.out.println("索引添加结果:"+addIndexResponse.getResult());
    }

    /**
     * 测试根据文档id查询
     * @throws IOException
     */
    @Test
    public void testqueryDoucmentById() throws IOException {
        GetRequest getRequest=new GetRequest("index_java","doc","88FLonEBUeUxCRIUGDI3");
        GetResponse getResponse = highLevelClient.get(getRequest);
        //是否存在的标记
        System.out.println(getResponse.isExists());
        //返回查询到的结果,不存在时返回null
        Map<String, Object> sourceMap = getResponse.getSource();
        System.out.println(sourceMap);
    }

    @Test
    public void testUpdateDocumentById() throws IOException {
        UpdateRequest updateRequest=new UpdateRequest("index_java","doc","YnxWpHEBEZO0aa-_KafP");
        Map<String,String> jsonMap=new HashMap<>();
        jsonMap.put("name","测试客户端更新文档2.0");
        jsonMap.put("description","这是通过java客户端更新的第一篇文档");
        jsonMap.put("studymodel","1");
        jsonMap.put("pic","d:/123.jpg");
        updateRequest.doc(jsonMap);
        UpdateResponse updateResponse = highLevelClient.update(updateRequest);
        System.out.println(updateResponse.status());
    }

    /**
     * 根据文档id删除,不知道id时可以先查询出对应的文档,再根据id删除
     * @throws IOException
     */
    @Test
    public void testdeleteDocumentById() throws IOException {
        DeleteRequest deleteRequest=new DeleteRequest("index_java","doc","YXxVpHEBEZO0aa-_hacp");
        DeleteResponse deleteResponse = highLevelClient.delete(deleteRequest);
        System.out.println(deleteResponse.status());
    }

    @Test
    public void testSearchAll() throws IOException {
        SearchRequest searchRequest=new SearchRequest("index_java");
        //设置类型
        searchRequest.types("doc");
        //创建查询条件
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());

        //设置分页条件
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(4);

        //添加排序
        searchSourceBuilder.sort(new FieldSortBuilder("studymodel").order(SortOrder.DESC));


        searchRequest.source(searchSourceBuilder);

        //执行查询
        SearchResponse searchResponse = highLevelClient.search(searchRequest);

        //解析结果
        SearchHits hits = searchResponse.getHits();
        for (SearchHit searchHit : hits.getHits()) {
            String index=searchHit.getIndex();
            String id=searchHit.getId();
            String sourceAsString = searchHit.getSourceAsString();
            System.out.println("sourceString:"+sourceAsString);
            System.out.println("-------------");
        }
        //取出高亮字段
        for (SearchHit searchHit : hits.getHits()) {
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            System.out.println(sourceAsMap);
            String name = (String) sourceAsMap.get("name");
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            System.out.println(highlightFields);
            if(highlightFields!=null){
                HighlightField nameField = highlightFields.get("name");
                if(nameField!=null){
                    Text[] fragments = nameField.getFragments();
                    StringBuffer stringBuffer = new StringBuffer();
                    for (Text str : fragments) {
                        stringBuffer.append(str.string());
                    }
                    name = stringBuffer.toString();
                    System.out.println(name);
                }
            }
        }
    }

    /**
     * term查询,搜索关键词不进行分词,直接和倒排索引匹配,如果文档中的字段进行了分词,就可能会查不到
     */
    @Test
    public void testTermQuery() throws IOException {
        SearchRequest searchRequest=new SearchRequest("index_java");
        searchRequest.types("doc");
        //添加查询条件
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termQuery("name","es自学"));
        searchRequest.source(searchSourceBuilder);

        //进行查询
        SearchResponse searchResponse = highLevelClient.search(searchRequest);

        //解析查询结果;
        SearchHits hits = searchResponse.getHits();
        System.out.println("查询到的总记录数:"+hits.getTotalHits());
        for (SearchHit searchHit : hits.getHits()) {
            System.out.println(searchHit.getSourceAsString());
            System.out.println("-------------");
        }
    }

    /**
     * 全文检索,先对搜索关键字进行分词,再用分词的结果依次搜索
     */
    @Test
    public void testMatchQuery() throws IOException {
        SearchRequest searchRequest=new SearchRequest("index_java");
        searchRequest.types("doc");
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery("name","es自学"));

        //高亮显示设置
        HighlightBuilder highlightBuilder=new HighlightBuilder();
        highlightBuilder.preTags("<tag>");
        highlightBuilder.postTags("</tag>");
        highlightBuilder.fields().add(new HighlightBuilder.Field("name"));

        searchSourceBuilder.highlighter(highlightBuilder);

        searchRequest.source(searchSourceBuilder);

        //执行搜索
        SearchResponse searchResponse = highLevelClient.search(searchRequest);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit searchHit : hits.getHits()) {
            System.out.println(searchHit.getSourceAsString());
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            System.out.println(highlightFields);
            System.out.println("-------------");
        }
    }

    /**
     * 布尔查询,must表示与,should表示或
     * @throws IOException
     */
    @Test
    @SuppressWarnings("all")
    public void testBooleanMustQuery() throws IOException {
        SearchRequest searchRequest=new SearchRequest("index_java");
        searchRequest.types("doc");
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("studymodel","自学"))
        .must(QueryBuilders.matchQuery("description","2")));
        searchRequest.source(searchSourceBuilder);
        //执行搜索
        SearchResponse searchResponse = highLevelClient.search(searchRequest);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit searchHit : hits.getHits()) {
            System.out.println(searchHit.getSourceAsString());
            System.out.println("-------------");
        }
    }

    /**
     * 测试根据一个关键字匹配多个字段,和或查询类似
     */
    @Test
    public void testMultiQuery() throws IOException {
        SearchRequest searchRequest=new SearchRequest("index_java");
        searchRequest.types("doc");
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.multiMatchQuery("学习","name","description"));
        //设置查询结果中要显示的字段和不显示的字段
        searchSourceBuilder.fetchSource(new String[]{"name"},new String[]{""});
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = highLevelClient.search(searchRequest);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit searchHit : hits.getHits()) {
            System.out.println(searchHit.getSourceAsString());
            System.out.println("-------------");
        }
    }

    /**
     * 过滤器测试,过滤器针对搜索的结果进行过滤,性能比查询要好,只能在布尔查询器上添加过滤器
     */
    @Test
    @SuppressWarnings("all")
    public void testFilter() throws IOException {
        SearchRequest searchRequest=new SearchRequest("index_java");
        searchRequest.types("doc");
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.matchQuery("studymodel", "自学"));
        //添加过滤器
        boolQueryBuilder.filter(QueryBuilders.termQuery("name","1"));//过滤name含有1的记录,

        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        //执行搜索
        SearchResponse searchResponse = highLevelClient.search(searchRequest);
        SearchHits hits = searchResponse.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit searchHit : hits.getHits()) {
            System.out.println(searchHit.getSourceAsString());
            System.out.println("-------------");
        }
    }

}