索引库管理

创建索引库

一、添加依赖

<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>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

二、代码

步骤:

  1. 创建一个maven工程。
  2. 添加jar包
  3. 创建一个Settings对象,设置cluster.name属性
  4. 创建一个TransportClient对象,基于Settings对象创建。PreBuiltTransportClient
  5. 把服务端的节点的ip及端口号添加到TransportClient对象中。
  6. 使用client对象实现索引的管理、文档的管理
  7. 关闭client

注意:

  1. 设置cluster.name属性,该属性值在elasticsearch.yml文件中,或者在在这里插入图片描述
  2. 必须添加所有服务端的节点,这样才能保证集群的高可用(只添加一个,集群虽然可以用,但如果那个节点挂了,会导致整个集群不可用)
@Test
    public void createIndex() throws Exception {
        //3、创建一个Settings对象,设置cluster.name属性
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        //	4、创建一个TransportClient对象,基于Settings对象创建。PreBuiltTransportClient
        TransportClient client = new PreBuiltTransportClient(settings);
        //	5、把服务端的节点的ip及端口号添加到TransportClient对象中。
        client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301));
        client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));
        client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9303));
        //	6、使用client对象实现索引的管理、文档的管理
        client.admin()
                .indices()
                //设置要创建的索引库的名称
                .prepareCreate("blog")
                //执行操作
                .get();
        //	7、关闭client
        client.close();
    }

设置mapping信息

一、创建索引库的时候设置mappings信息

注意:使用XContentBuilder对象描述一个json数据

@Test
    public void createIndexWithMapping() throws Exception {
        //1、创建一个client对象
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        TransportClient client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302))
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9303));
        //2、XContentBuilder对象描述一个json数据
        /*{
            "mappings":{
            "article":{
                "properties":{
                    "id":{
                        "type":"long",
                                "store":true
                    },
                    "title":{
                        "type":"text",
                                "store":"true",
                                "analyzer":"ik_max_word"
                    },
                    "content":{
                        "type":"text",
                                "store":"true",
                                "analyzer":"ik_max_word"
                    }
                }
            }
        }
        }*/
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                    .startObject("mappings")
                        .startObject("article")
                            .startObject("properties")
                                .startObject("id")
                                    .field("type","long")
                                    .field("store", true)
                                .endObject()
                                .startObject("title")
                                    .field("type", "text")
                                    .field("store", true)
                                    .field("analyzer", "ik_max_word")
                                .endObject()
                                .startObject("content")
                                    .field("type", "text")
                                    .field("store", true)
                                    .field("analyzer", "ik_max_word")
                                .endObject()
                            .endObject()
                        .endObject()
                    .endObject()
                .endObject();
        //3、使用client创建索引库,设置mapping信息
        client.admin()
                .indices()
                .prepareCreate("blog3")
                //设置mappings信息
                .setSource(builder)
                .get();
        //4、关闭连接
        client.close();
    }

二、先创建所有后设置mapping(创建client省略)

@Before
    public void init() throws Exception {
        //1、创建一个client对象
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302))
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9303));
    }

步骤:
1、创建一个client对象
2、使用client设置mapping信息preparePutMapping
3、关闭client

@Test
    public void putMapping() {
        //1、创建一个client对象
        //创建mapping的定义
        String mapping = "{\n" +
                "\t\t\t\t\"article\":{\n" +
                "\t\t\t\t\t\"properties\":{\n" +
                "\t\t\t\t\t\t\"id\":{\n" +
                "\t\t\t\t\t\t\t\"type\":\"long\",\n" +
                "\t\t\t\t\t\t\t\"store\":true\n" +
                "\t\t\t\t\t\t},\n" +
                "\t\t\t\t\t\t\"title\":{\n" +
                "\t\t\t\t\t\t\t\"type\":\"text\",\n" +
                "\t\t\t\t\t\t\t\"store\":\"true\",\n" +
                "\t\t\t\t\t\t\t\"analyzer\":\"ik_max_word\"\n" +
                "\t\t\t\t\t\t},\n" +
                "\t\t\t\t\t\t\"content\":{\n" +
                "\t\t\t\t\t\t\t\"type\":\"text\",\n" +
                "\t\t\t\t\t\t\t\"store\":\"true\",\n" +
                "\t\t\t\t\t\t\t\"analyzer\":\"ik_max_word\"\n" +
                "\t\t\t\t\t\t}\n" +
                "\t\t\t\t\t}\n" +
                "\t\t\t\t}\n" +
                "\t\t\t}";
        //2、使用client设置mapping信息
        client.admin()
                .indices()
                //设置要设置mapping的索引库的名称
                .preparePutMapping("blog")
                //设置type的名称
                .setType("article")
                //type的定义
                .setSource(mapping, XContentType.JSON)
                //执行操作
                .get();
        //3、关闭client
        client.close();
    }

删除索引库

步骤:
1)创建一个client对象
2)使用client的方法删除索引库prepareDelete参数就是索引库的名称
3)关闭client

@Test
    public void deleteIndex() {
        client.admin()
                .indices()
                .prepareDelete("blog2", "hello")
                .get();
    }

文档管理

添加文档

1)创建一个Client对象
2)创建一个文档对象,XContentBuilder描述一个文档。
3)使用client把文档对象写入索引库。
4)关闭client

@Test
    public void addDocument() throws Exception {
        //1)创建一个Client对象
        //2)创建一个文档对象,XContentBuilder描述一个文档。
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                .field("id", 1)
                .field("title", "一篇自媒体文章就让百度股价跌6%?别逗了")
                .field("content", "测试文档的内容")
                .endObject();
        //3)使用client把文档对象写入索引库。
        client.prepareIndex("blog", "article", "1")
                //设置文档信息
                .setSource(builder)
                //执行操作
                .get();
        //4)关闭client
        client.close();
    }

如果需要使用对象来添加文档:
定义article类(省略),使用jackson来转换json

添加文档

@Test
    public void addDocument2() throws Exception {
        for (int i = 2; i < 30; i++) {
            //创建一个文档对象
            Article article = new Article();
            article.setId(i);
            article.setTitle("达沃斯论坛大幕拉开,重要议题看这里!" + i);
            article.setContent("“雪龙”船碰撞冰山,南极科考有多难?比月球了解少" + i);
            //把article对象转换成json
            ObjectMapper objectMapper = new ObjectMapper();
            String doc = objectMapper.writeValueAsString(article);
            System.out.println(doc);
            //使用client把文档写入索引库
            client.prepareIndex()
                    //索引库的名称
                    .setIndex("blog")
                    //type的名称
                    .setType("article")
                    //文档的id
                    .setId("" + i)
                    //设置文档对象
                    .setSource(doc, XContentType.JSON)
                    .get();

        }
        client.close();
    }

修改文档

一、可以直接使用添加文档的方法实现修改。

@Test
    public void addDocument() throws Exception {
        //1)创建一个Client对象
        //2)创建一个文档对象,XContentBuilder描述一个文档。
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                .field("id", 1)
                .field("title", "测试更新")
                .field("content", "测试文档的内容")
                .endObject();
        //3)使用client把文档对象写入索引库。
        client.prepareIndex("blog", "article", "1")
                //设置文档信息
                .setSource(builder)
                //执行操作
                .get();
        //4)关闭client
        client.close();
    }

二、es的api中有更新文档的方法
prepareUpdate方法

@Test
    public void updateDocument() throws Exception {
        //创建一个文档对象
        Article article = new Article();
        article.setId(1);
        article.setTitle("落马8天后,赵正永首次被官方定性!");
        article.setContent("想坐收中美摩擦“渔翁之利”?这个国家想的有点多");
        //把article对象转成json
        String doc = new ObjectMapper().writeValueAsString(article);
        //更新文档
        client.prepareUpdate("blog", "article", "1")
                .setDoc(doc, XContentType.JSON)
                .get();
        client.close();
    }

删除文档

根据文档id(_id)删除文档

@Test
    public void deleteDocument() throws Exception {
        client.prepareDelete("blog", "article", "2").get();
    }

文档查询

步骤:
1)创建一个client对象
2)创建一个QueryBuilder对象,查询条件。使用QueryBuilders工具类创建。
3)使用client对象执行查询
设置查询的索引库、type、查询条件
4)执行查询,并返回查询结果。QueryResponse对象。
5)从QueryResponse对象中取查询结果。
6)取查询结果的总记录数。
7)取查询结果列表

根据id查询

QueryBuilders.idsQuery().addIds("查询的id")
@Test
    public void findById() throws Exception {
        //1)创建一个client对象
        //2)创建一个QueryBuilder对象,查询条件。使用QueryBuilders工具类创建。
        QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1");
        //3)使用client对象执行查询
        //设置查询的索引库
        //设置查询的索引库、type、查询条件
        SearchResponse response = client.prepareSearch("blog")
                //设置查询的type
                .setTypes("article")
                //设置查询条件
                .setQuery(queryBuilder)
                //执行查询
                .get();
        //4)执行查询,并返回查询结果。QueryResponse对象。
        //5)从QueryResponse对象中取查询结果。
        SearchHits searchHits = response.getHits();
        //6)取查询结果的总记录数。
        long totalHits = searchHits.getTotalHits();
        System.out.println("查询结果总记录数:" + totalHits);
        //8)取查询结果列表
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            //文档对象使用map表示
            Map<String, Object> source = hit.getSource();
            System.out.println(source);
        }
    }

根据term查询

关键词,term包含两部分内容:

  • 关键字所在的字段
  • 关键词本身。

关键词必须是关键词列表中存在的关键词,否则就没有结果。

QueryBuilders.termQuery("title", "落马")
@Test
    public void findByTerm() {
        //创建查询条件
        QueryBuilder queryBuilder = QueryBuilders.termQuery("content", "南极");
        //执行查询
        SearchResponse response = client.prepareSearch("blog")
                .setTypes("article")
                .setQuery(queryBuilder)
                .get();
        SearchHits searchHits = response.getHits();
        System.out.println("总记录数:" + searchHits.getTotalHits());
        Iterator<SearchHit> iterator = searchHits.iterator();
        while(iterator.hasNext()) {
            SearchHit hit = iterator.next();
            Map<String, Object> source = hit.getSource();
            System.out.println(source);
        }
    }

注意:term查询默认进行分页处理,每页默认显示10条数据

根据query_string查询

先对查询的内容分词,然后基于分词之后的结果进行查询。

QueryBuilders.queryStringQuery("查询条件").defaultField("title")
@Test
    public void findByQueryString() {
        //创建查询条件
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("雪龙的伤害有多大").defaultField("content");
        //执行查询
        SearchResponse response = client.prepareSearch("blog")
                .setTypes("article")
                .setQuery(queryBuilder)
                .get();
        SearchHits searchHits = response.getHits();
        System.out.println("总记录数:" + searchHits.getTotalHits());
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSource());
        }

    }

注意:也默认进行了分页处理,只显示10条数据

分页处理

设置分页信息,需要设置两个参数:

  • from:起始的行号。默认从0开始。
  • size:每页显示的行数,默认是10

在client对象中设置。

@Test
    public void findByQueryString() {
        //创建查询条件
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("雪龙的伤害有多大").defaultField("content");
        //执行查询
        SearchResponse response = client.prepareSearch("blog")
                .setTypes("article")
                .setQuery(queryBuilder)
                //设置分分页信息
                //取第二页信息
                .setFrom(5)
                .setSize(5)
                .get();
        SearchHits searchHits = response.getHits();
        System.out.println("总记录数:" + searchHits.getTotalHits());
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSource());
        }

    }

高亮显示

在关键词前后分别添加前缀和后缀。
1)执行查询之前需要设置高亮的条件

  1. 高亮显示的字段
  2. 高亮显示的前缀
  3. 高亮显示的后缀

2)执行查询
3)取高亮结果
高亮结果不会在查询结果的文档中反映出来。
需要单独取高亮结果。从SearchHit对象中取高亮结果。

@Test
    public void findByHighlighting() {
        //查询条件
        QueryBuilder queryBuilder = QueryBuilders.termQuery("content", "雪龙");
        //查询之前先设置高亮信息
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                //设置高亮显示的字段
                .field("content")
                //设置高亮显示的前缀
                .preTags("<em>")
                //设置高亮显示的后缀
                .postTags("</em>");
        //执行查询
        SearchResponse response = client.prepareSearch("blog")
                .setTypes("article")
                //查询条件
                .setQuery(queryBuilder)
                //高亮条件
                .highlighter(highlightBuilder)
                .get();
        //取查询结果
        SearchHits searchHits = response.getHits();
        //总记录数
        long totalHits = searchHits.getTotalHits();
        System.out.println("总记录数:" + totalHits);
        //取结果列表
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            Map<String, Object> doc = hit.getSource();
            System.out.println(doc);
            //取高亮的结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            //根据高亮字段取高亮结果
            HighlightField highlightField = highlightFields.get("content");
            //高亮的结果,一般情况下只有一个值。
            Text[] fragments = highlightField.getFragments();
            Text fragment = fragments[0];
            //最终的高亮结果
            String hlContent = fragment.string();
            System.out.println(hlContent);

        }
    }
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐