侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

绿泡泡:___zze,添加备注来意

  • 累计撰写 748 篇文章
  • 累计创建 65 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

Elasticsearch(7)之使用Java客户端管理ES

zze
zze
2019-08-25 / 0 评论 / 0 点赞 / 677 阅读 / 15269 字

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>xyz.zze</groupId>
    <artifactId>es_demo1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <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>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

创建索引库

// 1、创建一个 Settings 对象,相当于是一个配置信息,主要配置集群的名称
Settings settings = Settings.builder()
        .put("cluster.name", "my-elasticsearch")     // 设置 ES 集群的名称,就是上一节配置中 cluster.name 对应的值
        .build();
// 2、创建一个客户端 Client 对象
TransportClient client = new PreBuiltTransportClient(settings);
// 3、配置集群各个节点的通信地址
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301));
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));
// 4、使用 client 对象创建一个索引库
client.admin().indices()
        .prepareCreate("test_index") // 设置索引库名称
        .get();// 执行
// 5、关闭 client 对象
client.close();

执行后查看 head 页面,可以看到成功创建了索引。

image.png

设置 mappings

// 1、创建一个 Settings 对象
Settings settings = Settings.builder()
        .put("cluster.name", "my-elasticsearch")     // 设置 ES 集群的名称,就是上一节配置中 cluster.name 对应的值
        .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 对象,对应 json 表现形式如下
{
    "mappings": {
        "article": {
            "properties": {
                "id": {
                    "type": "long",
                    "store": true
                },
                "title": {
                    "type": "text",
                    "store": true,
                    "index": true,
                    "analyzer": "ik_smart"
                },
                "content": {
                    "type": "text",
                    "store": true,
                    "index": true,
                    "analyzer": "ik_smart"
                }
            }
        }
    }
}
*/
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("index",true)
                        .field("analyzer","ik_smart")
                    .endObject()
                    .startObject("content")
                        .field("type","text")
                        .field("store",true)
                        .field("index",true)
                        .field("analyzer","ik_smart")
                    .endObject()
                .endObject()
            .endObject()
        .endObject();
// 4、使用 client 向 es 服务器发送 mapping 信息
client.admin().indices()
        // 设置要做映射的索引
        .preparePutMapping("test_index")
        // 设置 Type
        .setType("article")
        // 设置具体的 mapping 信息,可以是 xContentBuilder 对象也可以是 json 字符串
        .setSource(xContentBuilder)
        // 执行操作
        .get();
// 5、关闭 client 对象
client.close();

执行完上述操作后,查看索引库会发现映射信息已设置成功。

image.png

添加文档

方式一:XContentBuilder

// 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"), 9300))
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));
// 2、创建一个文档对象
XContentBuilder documentBuilder = XContentFactory.jsonBuilder()
            .startObject()
                .field("id",1l)
                .field("title","测试标题")
                .field("content","测试内容")
            .endObject();
// 3、把文档对象添加到索引库
client.prepareIndex()
        // 设置索引名称
        .setIndex("test_index")
        // 设置 Type
        .setType("article")
        // 设置 Id
        .setId("1")
        // 设置文档信息
        .setSource(documentBuilder)
        // 执行操作
        .get();

使用 head 插件查看添加的内容:

image.png

Json字符串

1、创建 Article 实体。

//  xyz.zze.pojo.Article;
import lombok.Data;

@Data
public class Article {

    private long id;
    private String title;
    private String content;
}

2、添加 Jackson 依赖。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.8.11</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.8.11</version>
</dependency>

3、编写代码。

// 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"), 9300))
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));
// 2、创建一个文档对象
Article article = new Article();
article.setId(2);
article.setTitle("测试标题2");
article.setContent("测试内容2");
// 3、把 Article 对象转换为 json 格式的字符串
ObjectMapper objectMapper = new ObjectMapper();
String jsonDoc = objectMapper.writeValueAsString(article);
// 4、把文档对象添加到索引库
client.prepareIndex()
        // 设置索引名称
        .setIndex("test_index")
        // 设置 Type
        .setType("article")
        // 设置 Id
        .setId("2")
        // 设置文档信息
        .setSource(jsonDoc, XContentType.JSON)
        // 执行操作
        .get();

执行完上述操作后使用 head 插件查看数据:

image.png

查询文档操作

根据id查询

// 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"), 9300))
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9301))
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9302));
// 2、创建一个查询对象
QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("1", "2");
// 3、执行查询
SearchResponse searchResponse = client.prepareSearch("test_index")
        .setTypes("article")
        .setQuery(queryBuilder)
        .get();
// 4、取查询结果
// 获取命中的记录
SearchHits hits = searchResponse.getHits();
// 取命中记录的条数
long totalHits = hits.totalHits;
System.out.println("命中记录数:"+totalHits);
// 遍历命中的记录
Iterator<SearchHit> iterator = hits.iterator();
while (iterator.hasNext()){
    SearchHit hit = iterator.next();
    // 输出命中的记录,Json 格式
    System.out.println(hit.getSourceAsString());
    // 取文档的属性
    Map<String, Object> source = hit.getSource();
    Object id = source.get("id");
    Object title = source.get("title");
    Object content = source.get("content");
}
// 5、关闭 client
client.close();

控制台输出信息如下:

命中记录数:2
{"id":2,"title":"测试标题2","content":"测试内容2"}
{"id":1,"title":"测试标题","content":"测试内容"}

根据term查询

只需要将根据 id 查询示例中创建 QueryBuilder 对象替换为下面这行即可:

QueryBuilder queryBuilder = QueryBuilders.termQuery("title","测试");

控制台输出信息如下:

命中记录数:2
{"id":2,"title":"测试标题2","content":"测试内容2"}
{"id":1,"title":"测试标题","content":"测试内容"}

根据querystring查询

只需要将根据 id 查询示例中创建 QueryBuilder 对象替换为下面这行即可:

QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("测试使用querystring查询")
                    .defaultField("title"); // 指定查询的域,若不指定则在所有域中进行查询

控制台输出信息如下:

命中记录数:2
{"id":2,"title":"测试标题2","content":"测试内容2"}
{"id":1,"title":"测试标题","content":"测试内容"}

分页处理

分页信息是在创建 SearchResponse 对象时进行设置的,如下:

SearchResponse searchResponse = client.prepareSearch("test_index")
                .setTypes("article")
                .setQuery(queryBuilder)
                .setFrom(0)     // 设置起始记录的索引,从 0 开始
                .setSize(1)     // 设置每页记录的条数
                .get();

高亮查询关键字

// 创建高亮显示配置信息对象
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");  // 设置需要高亮显示的域
highlightBuilder.preTags("<em>");
highlightBuilder.postTags("</em>");

Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
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));
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("测试使用querystring查询")
        .defaultField("title");

SearchResponse searchResponse = client.prepareSearch("test_index")
        .setTypes("article")
        .setQuery(queryBuilder)
        .setFrom(1)
        .setSize(2)
        .highlighter(highlightBuilder) // 指定高亮显示配置
        .get();
SearchHits hits = searchResponse.getHits();
Iterator<SearchHit> iterator = hits.iterator();
while (iterator.hasNext()){
    SearchHit hit = iterator.next();
    // 输出所有高亮显示的域内容
    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
    System.out.println(highlightFields);
    // 获取指定域的高亮结果文本内容
    HighlightField titleField = highlightFields.get("title");
    Text[] titleFragments = titleField.getFragments();
    if(titleFragments!=null && titleFragments.length>=0){
        String title = titleFragments[0].toString();
        System.out.println(title);
    }
}
client.close();

控制台输出结果如下:

{title=[title], fragments[[<em>测试</em>标题]]}
<em>测试</em>标题
{title=[title], fragments[[<em>测试</em>标题3]]}
<em>测试</em>标题3
0

评论区