Java客户端操作索引库

Posted 小乞丐程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java客户端操作索引库相关的知识,希望对你有一定的参考价值。

ElasticSearch第二天

学习目标:

  1. 能够使用java客户端完成创建、删除索引的操作
  2. 能够使用java客户端完成文档的增删改的操作
  3. 能够使用java客户端完成文档的查询操作
  4. 能够完成文档的分页操作
  5. 能够完成文档的高亮查询操作
  6. 能够搭建Spring Data ElasticSearch的环境
  7. 能够完成Spring Data ElasticSearch的基本增删改查操作
  8. 能够掌握基本条件查询的方法命名规则

第一章 ElasticSearch编程操作

1.1 创建工程,导入坐标

pom.xml坐标

<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

 @Test
    public void createIndex() throws Exception 
        //创建一个Setings对象 相当于是一个配置信息,主要配置集群的名称
        Settings build = Settings.builder()
                                .put("cluster.name","my-elasticsearch")
                                .build();
        ///创建一个客户端Client对象
        TransportClient client = new PreBuiltTransportClient(build);
        client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9301));
        client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9302));
        client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9303));

        /// 创建client对象创建索引库 //执行操作
        client.admin().indices().prepareCreate("index_hello").get();
        //关闭client对象
        client.close();
    


1.3 创建映射mapping

public void setMappings() throws Exception 
        //创建一个Settings对象
        Settings settings = Settings.builder()
                .put("cluster.name", "my-elasticsearch")
                .build();
        ///创建一个TransportClient对象
        TransportClient client = new PreBuiltTransportClient(settings)
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9301))
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9302))
                .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9303));

        //创建一个Mappings信息
        XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
                .startObject()
                 .startObject("article")
                    .startObject("properties")
                        .startObject("id")
                            .field("type","long")
                            .field("store",true)
                        .endObject()
                        .startObject("title")
                            .field("type","text")
                            .field("store",true)
                            .field("analyzer","ik_smart")
                        .endObject()
                        .startObject("content")
                            .field("type","text")
                            .field("store",true)
                            .field("analyzer","ik_smart")
                        .endObject()
                    .endObject()
                .endObject()
                .endObject();

        //使用client把mapping信息设置到索引中
        client.admin().indices()
                    //设置要做映射的索引
                    .preparePutMapping("index_hello")
                    //设置要做映射的type
                    .setType("article")
                    //mapping信息,可以是XContentBuilder对象也可以是字符串也可以是json格式
                    .setSource(xContentBuilder)
                    //执行操作
                    .get();
        //关闭客户端
        client.close();
    


1.4 建立文档document

1.4.1 建立文档(通过XContentBuilder)

 //添加文档
    @Test
    public void testAddDocument() throws  Exception 

        //创建一个client对象
        //创建一个文档对象
        XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
                .startObject()
                    .field("id",1l)
                    .field("title","北方入秋速度明显加快,多地降温幅度最多可达10度")
                    .field("content","阿联酋一架客机在纽约基础被隔离,10名乘客病例")
                .endObject();
        //把文档对象添加到索引库
        ///设置索引名称 type 设置文档id,如果不设置的话自动的生成一个id 设置文档信息
        client.prepareIndex("index_hello","article","1").setSource(xContentBuilder).get();

        //关闭客户端
        client.close();


    

1.4.2 建立文档(使用Jackson转换实体)

1)创建Article实体

public class Article 
	private Integer id;
	private String title;
	private String content;
    getter/setter...

2)添加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 Exception 
            ///创建Article对象
        Article article = new Article();
        //设置对象的属性
        article.setId(3);
        article.setTitle("MH370坠毁在柬埔寨密林?");
        article.setContent("警惕荒唐的死亡游戏!饿15岁少年");
            //把article对象转换成json格式的字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonDocument = objectMapper.writeValueAsString(article);
        System.out.println(jsonDocument);
        //关闭客户端
        client.prepareIndex("index_hello","article","3").setSource(jsonDocument, XContentType.JSON).get();
        client.close();
    

1.5 查询文档操作

2.5.2 使用文档ID查询文档

@Test
    public void testSearchById() throws Exception 
        // 创建一个client对象
        //创建一个查询对象
        QueryBuilder QueryBuilder = QueryBuilders.idsQuery().addIds("1","2");
        //执行查询
        SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(QueryBuilder).get();
        //取查询结果
        SearchHits hits = searchResponse.getHits();
        //取查询结果的总记录数
        System.out.println("查询结果总记录数:"+hits.getTotalHits());
        //查询结果列表
        Iterator<SearchHit> iterator = hits.iterator();
        while (iterator.hasNext())
            SearchHit next = iterator.next();
            //打印文档对象,以json格式输出
            System.out.println(next.getSourceAsString());
            //取文档的属性
            System.out.println("文档的属性");
            Map<String,Object> document = next.getSource();
            System.out.println(document.get("id"));
            System.out.println(document.get("title"));
            System.out.println(document.get("content"));
        
        //关闭client
        client.close();
    

1.5.1关键词查询

@Test
    public void testQueryByTerm() throws Exception
        ///创建一个QueryBuilder对象
        // name 要搜索的字段 value 要搜索的关键词
        QueryBuilder queryBuilder = QueryBuilders.termQuery("title","北方");
        search(queryBuilder);
    

2.5.2 字符串查询

@Test
public void testQueryStringQuery() throws Exception
//创建一个QueryBuilder对象
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(“速度与激情”).defaultField(“title”); //默认搜索域 defaultField
search(queryBuilder);

2.6.2 分页查询

@Test
    public void testQueryStringQuery1() throws Exception
        //创建一个QueryBuilder对象
        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("打算").defaultField("title"); //默认搜索域 defaultField
        search1(queryBuilder);
    

2.7 查询结果高亮操作

2.7.1 什么是高亮显示

在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮

百度搜索关键字"传智播客"

京东商城搜索"笔记本"

2.7.2 高亮显示的html分析

通过开发者工具查看高亮数据的html代码实现:

ElasticSearch可以对查询出的内容中关键字部分进行标签和样式的设置,但是你需要告诉ElasticSearch使用什么标签对高亮关键字进行包裹

2.7.3 高亮显示代码实现

//设置高亮显示
@Test
public void testQueryStringQuery3() throws Exception
//创建一个QueryBuilder对象
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(“打算”).defaultField(“title”); //默认搜索域 defaultField
search2(queryBuilder,“title”);

整体代码

package com.itheima.es;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.IdsQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import java.net.InetAddress;
import java.util.Iterator;
import java.util.Map;

public class ElasticSearchClientTest 


    private  TransportClient client;

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

Elasticsearch:在 Java 客户端应用中管理索引 - Elastic Stack 8.x

管理索引是客户端应用常用的一些动作,比如我们创建,删除,打开 及关闭索引等操作。在今天的文章中,我将描述如何在 Java 客户端应用中对索引进行管理。

前提条件

我们需要阅读之前的文章 “Elasticsearch:在 Java 客户端中使用 truststore 来创建 HTTPS 连接”。在那篇文章中,我们详述了如何在 Java 客户端应用中和 Elasticsearch 建立连接。在这里就不再累述了。

为了方便大家的阅读,我创建了如下的一个 github 仓库:GitHub - liu-xiao-guo/elasticsearchjava-manage-index

代码

在代码中我创建了如下的一个 class:

IndexOperations.java

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import co.elastic.clients.json.JsonpMapper;
import jakarta.json.Json;
import jakarta.json.stream.JsonParser;

import java.io.IOException;
import java.io.StringReader;

public class IndexOperations 
    private final ElasticsearchClient client;
    public IndexOperations(ElasticsearchClient client)
         this.client = client; 

    // Check whether an index exists or not
    public boolean checkIndexExists(String name) throws IOException 
        return client.indices().exists(c -> c.index(name)).value();
    

    // Create an index if it does not exist
    public void createIndex(String name) throws IOException 
        client.indices().create(c -> c.index(name));
    

    // Delete an index if it exists
    public void deleteIndex(String name) throws IOException 
        client.indices().delete(c -> c.index(name));
    

    // Close an index
    public void closeIndex(String name) throws IOException 
        client.indices().close(c -> c.index(name));
    

    // Open an index
    public void openIndex(String name) throws IOException 
        client.indices().open(c -> c.index(name));
    

    // Create an index with mappings defined
    public void putMapping(String index, String mappings) throws IOException 
        JsonpMapper mapper = client._transport().jsonpMapper();
        JsonParser parser = Json.createParser(new StringReader(mappings));
        CreateIndexRequest request_create =  new CreateIndexRequest.Builder()
                .index(index)
                .mappings(TypeMapping._DESERIALIZER.deserialize(parser, mapper))
                .build();
        CreateIndexResponse response_create = client.indices().create(request_create);
    

通过这个 class 的使用,我们可以对一个索引进行 create,delete,open,close 及检查是否存在。关于使用 mapping 来创建索引,更多的信息可以参考文章 “Elasticsearch:在 Java 应用中创建 mappings,批量写入及更新 - Java client 8.x”。

在代码中,我们需要修改相应的部分创建 ElasticsearchClient 实例。我们使用如下的代码来示例化 IndexOperations:

ElasticsearchJava.java

       try 
            makeConnection_truststore();
         catch (CertificateException e) 
            e.printStackTrace();
         catch (NoSuchAlgorithmException e) 
            e.printStackTrace();
         catch (KeyStoreException e) 
            e.printStackTrace();
         catch (KeyManagementException e) 
            e.printStackTrace();
        

        IndexOperations io = new IndexOperations(client);

我们可以使用如下的代码来对索引的操作进行测试:

        io.createIndex(INDEX_NAME);
        Thread.sleep(1000);
        io.closeIndex(INDEX_NAME);
        io.openIndex(INDEX_NAME);
        io.deleteIndex(INDEX_NAME);

        String mappings = "\\n" +
                "  \\"properties\\" : \\n" +
                "    \\"id\\" : \\n" +
                "      \\"type\\" : \\"keyword\\" \\n" +
                "    ,\\n"+
                "    \\"name\\" : \\n" +
                "      \\"type\\" : \\"text\\",\\n" +
                "      \\"fields\\" : \\n" +
                "        \\"keyword\\" : \\n" +
                "          \\"type\\" : \\"keyword\\",\\n" +
                "          \\"ignore_above\\" : 256 \\n" +
                "        \\n" +
                "       \\n" +
                "    , \\n" +
                "    \\"price\\" :  \\n" +
                "      \\"type\\" : \\"long\\" \\n" +
                "      \\n" +
                "  \\n" +
                "\\n";

        io.putMapping("test1", mappings);

我们在代码中放置了 1 秒的延迟(Thread.wait(1000)) 以防止对索引的快速操作,因为它们的分片分配是异步的,并且它们需要几毫秒才能准备好。 最佳实践是不使用类似的 hack,而是在执行进一步操作之前轮询索引的状态,并且仅在它变为绿色时执行这些操作。

在上面的代码的最后部分,我们使用 io 来创建一个具有 mappings 的索引。执行完后,我们可以使用如下的命令来查看:

GET test1/_mapping

上面的命令显示:


  "test1": 
    "mappings": 
      "properties": 
        "id": 
          "type": "keyword"
        ,
        "name": 
          "type": "text",
          "fields": 
            "keyword": 
              "type": "keyword",
              "ignore_above": 256
            
          
        ,
        "price": 
          "type": "long"
        
      
    
  

以上是关于Java客户端操作索引库的主要内容,如果未能解决你的问题,请参考以下文章

Java客户端操作索引库

ElasticSearch-学习笔记04Java客户端操作索引库

我爱java系列之---如何把数据库中查到的Skulist数据转换成elastic索引库中SkuInfo类数据?

Elasticsearch:使用 Low Level Java 客户端来创建连接 - Elastic Stack 8.x

使用java客户端创建索引库

Elasticsearch:使用标准 Java HTTP 的集成 - Elastic Stack 8.x