一、ES编程操作

1.1 导入依赖坐标

  • pom.xml。本文使用的ES版本为5.6.8
<dependencies>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>5.6.8</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>transport</artifactId>
        <version>5.6.8</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-to-slf4j</artifactId>
        <version>2.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.24</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.21</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

1.2 创建索引index

  • 创建索引的步骤

    1. 创建一个Settings对象,相当于是一个配置信息。主要配置集群的名称。
    2. 创建一个客户端Client对象
    3. 使用client对象创建一个索引库
    4. 关闭client对象
@Test
public void createIndex() throws UnknownHostException {
    //1、创建一个Settings对象,相当于是一个配置信息。主要配置集群的名称。
    Settings settings = Settings.builder()
        .put("cluster.name", "my-elasticsearch")
        .build();
    //2、创建一个客户端Client对象
    TransportClient client = new PreBuiltTransportClient(settings)
        .addTransportAddress(
        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300))
        .addTransportAddress(
        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
        .addTransportAddress(
        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));
    //3、使用client对象创建一个索引库
    client.admin().indices().prepareCreate("blog").get();
    //4、关闭client对象
    client.close();
}

1.3 创建映射mapping

  • 创建设置映射的步骤

    1. 创建一个Settings对象
    2. 创建一个Client对象
    3. 创建一个mapping信息,应该是一个json数据,可以是字符串,也可以是XContextBuilder对象
    4. 使用client向es服务器发送mapping信息
    5. 关闭client对象
    @Test
    public void setMappings() throws IOException {
        //1)创建一个Settings对象
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        //2)创建一个Client对象
        TransportClient client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300))
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));

        //3)创建一个mapping信息,应该是一个json数据,可以是字符串,也可以是XContextBuilder对象
/*        {
            "article":{
                "properties":{
                    "id":{
                        "type":"long",
                        "index":"not_analyzed",
                        "store":true
                    }
                    "title":{
                        "type":"text",
                        "store":true,
                        "index":"analyzed",
                        "analyzer":"ik_smart"
                    }
                    "content":{
                        "type":"text",
                        "store":true,
                        "index":"analyzed",
                        "analyzer":"ik_smart"
                    }
                }
            }
        }*/
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                    .startObject("article")
                        .startObject("properties")
                            .startObject("id")
                                .field("type", "long")
                                .field("index", "not_analyzed")
                                .field("store", true)
                            .endObject()
                            .startObject("title")
                                .field("type", "text")
                                .field("store", true)
                                .field("index", "analyzed")
                                .field("analyzer", "ik_smart")
                            .endObject()
                            .startObject("content")
                                .field("type", "text")
                                .field("store", "true")
                                .field("index", "analyzed")
                                .field("analyzer", "ik_smart")
                            .endObject()
                        .endObject()
                    .endObject()
                .endObject();

        //4)使用client向es服务器发送mapping信息
        client.admin().indices().preparePutMapping("blog").setType("article").setSource(builder).get();
        //5)关闭client对象
        client.close();
    }
  • 注意:startObject()表示一个左大括号{endObject()表示一个右大括号}

1.4 建立添加文档document

1.4.1 XContentBuilder

  • 步骤

    1. 创建一个Settings对象
    2. 创建一个Client对象
    3. 创建一个文档对象,创建一个json格式的字符串,或者使用XContentBuilder
    4. 使用Client对象吧文档添加到索引库中
    5. 关闭client
    @Test
    public void testAddDocument() throws IOException {
        //1. 创建一个client对象
        //2. 创建一个文档对象
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                    .field("id", "1")
                    .field("title", "让民营企业创造活力迸发")
                    .field("content", "民营经济是社会主义市场经济发展的重要成果,是推动经济社会发展的重要力量。")
                .endObject();
        //3. 把文档添加到索引库
//        client.prepareIndex("blog", "article", "1").setSource(builder).get();
        client.prepareIndex()
                //设置索引
                .setIndex("blog")
                //设置type
                .setType("article")
                //设置id,如果不设置的话生成一个Id
                .setId("1")
                //设置文档信息
                .setSource(builder)
                //执行操作
                .get();
        //4. 关闭客户端
        client.close();
    }

1.4.2 使用Jackson将实体转为Json

  • 步骤

    1. 创建一个pojo类
    2. 使用工具类把pojo转换成json字符串
    3. 把文档写入索引库
  • 首先要创建实体类
public class Article {
    private long id;
    private String title;
    private String content;
}
  • 添加jackson依赖坐标
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.8.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.8.1</version>
</dependency>
  • 代码实现
@Test
public void testAddDocument2() throws JsonProcessingException {
    //创建一个pojo类
    Article article = new Article();
    article.setId(2l);
    article.setTitle("中央出台支持民营企业28条");
    article.setContent("《中共中央 国务院关于营造更好发展环境支持民营企业改革发展的意见》(以下简称《意见》)22日对外发布。意见提出优化公平竞争的市场环境,进一步放开民营企业市场准入,并提出一系列有针对性的举措,为民营企业参与市场竞争松绑开路,为企业改革发展壮大拓展空间。");
    //使用工具类把pojo转换成json字符串
    ObjectMapper mapper = new ObjectMapper();
    String jsonDocument = mapper.writeValueAsString(article);
    System.out.println(jsonDocument);
    //把文档写入索引库
    client.prepareIndex("blog", "article", "2")
        .setSource(jsonDocument, XContentType.JSON)
        .get();
    //关闭客户端
    client.close();
}

1.5 查询文档操作

  • 查询步骤

    1. 创建一个Client对象
    2. 创建一个查询对象,可以使用QueryBuilders工具类创建QueryBuilder对象。
    3. 使用client执行查询
    4. 得到查询的结果。
    5. 取查询结果的总记录数
    6. 取查询结果列表
    7. 关闭client

1.5.0 创建客户端对象client(@Before)

    @Before
    public void init() throws UnknownHostException {
        //1、创建一个Settings对象,相当于是一个配置信息。主要配置集群的名称。
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        //2、创建一个客户端Client对象
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(
                        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300))
                .addTransportAddress(
                        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
                .addTransportAddress(
                        new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));
    }

1.5.1 id查询

  • QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1", "2");
@Test
public void testQueryById() {
    //1)创建一个Client对象
    //2)创建一个查询对象,可以使用QueryBuilders工具类创建QueryBuilder对象。
    QueryBuilder builder = QueryBuilders.idsQuery().addIds("1", "2");

    //3)使用client执行查询
    SearchResponse searchResponse = client.prepareSearch("blog")
        .setTypes("article")
        .setQuery(builder)
        .get();
    //4)得到查询的结果。
    SearchHits hits = searchResponse.getHits();
    //5)取查询结果的总记录数
    System.out.println("查询的总记录数:" + hits.getTotalHits());
    //6)取查询结果列表
    Iterator<SearchHit> iterator = hits.iterator();
    while (iterator.hasNext()) {
        SearchHit searchHit = iterator.next();
        //以Json格式输出
        System.out.println(searchHit.getSourceAsString());
        //取文档的属性
        Map<String, Object> document = searchHit.getSource();
        System.out.println(document.get("id"));
        System.out.println(document.get("title"));
        System.out.println(document.get("content"));
    }
    //7)关闭client
    client.close();
}

1.5.2 关键词查询

  • QueryBuilder queryBuilder = QueryBuilders.termQuery("title", "北方");
@Test
public void testQueryByTerm() {
    //创建QueryBuilder对象
    //参数1:要搜索的字段
    //参数2:要搜索的关键词
    QueryBuilder builder = QueryBuilders.termQuery("title", "中央");
    //执行查询
    search(builder);
}

private void search(QueryBuilder builder) {
    //3)使用client执行查询
    SearchResponse searchResponse = client.prepareSearch("blog")
        .setTypes("article")
        .setQuery(builder)
        .get();
    //4)得到查询的结果。
    SearchHits hits = searchResponse.getHits();
    //5)取查询结果的总记录数
    System.out.println("查询的总记录数:" + hits.getTotalHits());
    //6)取查询结果列表
    Iterator<SearchHit> iterator = hits.iterator();
    while (iterator.hasNext()) {
        SearchHit searchHit = iterator.next();
        //以Json格式输出
        System.out.println(searchHit.getSourceAsString());
        //取文档的属性
        Map<String, Object> document = searchHit.getSource();
        System.out.println(document.get("id"));
        System.out.println(document.get("title"));
        System.out.println(document.get("content"));
    }
    //7)关闭client
    client.close();
}

1.5.3 字符串查询

  • QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("速度与激情").defaultField("title");
@Test
public void testQueryStirng() {
    //创建QueryBuilder对象
    QueryBuilder builder = QueryBuilders.queryStringQuery("中央").defaultField("title");
    //执行查询
    search(builder);
}

1.6 查询文档分页操作

  • client.prepareSearch("blog").setTypes("article").setQuery(builder).setFrom(0).setSize(5).get();
  • 设置setFromsetSize
    private void search(QueryBuilder builder) {
        //3)使用client执行查询
        SearchResponse searchResponse = client.prepareSearch("blog")
                .setTypes("article")
                .setQuery(builder)
                //设置分页信息 --------------!
                .setFrom(0)
                //每页显示的行数 ------------!
                .setSize(5)
                .get();
        //4)得到查询的结果。
        SearchHits hits = searchResponse.getHits();
        //5)取查询结果的总记录数
        System.out.println("查询的总记录数:" + hits.getTotalHits());
        //6)取查询结果列表
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext()) {
            SearchHit searchHit = iterator.next();
            //以Json格式输出
            System.out.println(searchHit.getSourceAsString());
            //取文档的属性
            Map<String, Object> document = searchHit.getSource();
            System.out.println(document.get("id"));
            System.out.println(document.get("title"));
            System.out.println(document.get("content"));
        }
        //7)关闭client
        client.close();
    }

1.7 查询结果高亮显示

  • 原理:将查询出来的结果用html标签包围

    • new一个HighlighterBuilder,设置高亮字段和要包裹的html标签
    • client.prepareSearch()设置.highlighter(highlighterBuilder)\
    //高亮查询
    private void search(QueryBuilder builder, String highlightField) {
        HighlightBuilder highlightBuilder = new HighlightBuilder();//---!
        //高亮显示的字段
        highlightBuilder.field(highlightField);//-----------------------!
        highlightBuilder.preTags("<em>");//-----------------------------!
        highlightBuilder.postTags("</em>");//---------------------------!
        //3)使用client执行查询
        SearchResponse searchResponse = client.prepareSearch("blog")
                .setTypes("article")
                .setQuery(builder)
                //设置分页信息
                .setFrom(0)
                //每页显示的行数
                .setSize(5)
                .highlighter(highlightBuilder)//------------------------!
                .get();
        //4)得到查询的结果。
        SearchHits hits = searchResponse.getHits();
        //5)取查询结果的总记录数
        System.out.println("查询的总记录数:" + hits.getTotalHits());
        //6)取查询结果列表
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext()) {
            SearchHit searchHit = iterator.next();
            //以Json格式输出
            System.out.println(searchHit.getSourceAsString());
            //取文档的属性
            System.out.println("-----------------文档属性--------------");
            Map<String, Object> document = searchHit.getSource();
            System.out.println(document.get("id"));
            System.out.println(document.get("title"));
            System.out.println(document.get("content"));
            System.out.println("-----------------高亮区域--------------");
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            System.out.println(highlightFields);
            //取高亮显示的结果
            HighlightField field = highlightFields.get("title");
            Text[] fragments = field.getFragments(); //一般来说每一条结果都只有一个title,索引取第一个就行
            if (fragments != null) { //判断结果是否为Null
                String title = fragments[0].toString();
                System.out.println(title);
            }
        }
        //7)关闭client
        client.close();
    }
Last modification:December 25th, 2019 at 09:55 am