1. 映射

1.1 字段类型(type)

1.1.1 字符串

1.1.1.1 text

  • 指定分析器analyzer会对文本进行分词
“name”: {
    "type": "text",
    "analyzer": "ik_max_word",
    "search_analyzer": "ik_smart",
    "index": true,
    "store": false
}
  • ik_max_word:最大粒度
  • ik_smart:智能

    • 索引时使用ik_max_word将搜索内容进行细粒度分词,搜索时使用ik_smart提高搜索精确性
  • index:指定是否索引,默认为index=true,即要进行索引,只有进行索引才可以从索引库搜索到。
  • store:是否在source之外存储,每个文档索引后会在 ES中保存一份原始文档,存放在"_source"中,一般情况下不需要设置storetrue,因为在_source中已经有一份原始文档了。

1.1.1.2 keyword

  • keyword字段为关键字字段,通常搜索keyword是按照整体搜索,所以创建keyword字段的索引时是不进行分词的,比如:邮政编码、手机号码、身份证等。keyword字段通常用于<font color="red">过滤、排序、聚合</font>等。

1.1.2 date日期类型

  • 日期类型不用设置分词器。通常日期类型的字段用于排序。
{
    "properties": {
        "timestamp": {
            "type": "date",
            "format": "yyyy‐MM‐dd HH:mm:ss||yyyy‐MM‐dd"
            }
    }
}
  • format:设置日期格式

1.1.3 数值类型

  • 尽量选择范围小的类型,提高搜索效率
  • 对于浮点数尽量用<font color="red">比例因子</font>scaling_factor

    • 假如比例因子为100,如果我们输入的价格是23.45则ES中会将23.45乘以100存储在ES中。
    • 如果输入的价格是23.456,ES会将23.456乘以100再取一个接近原始值的数,得出2346。
    • 使用比例因子的好处是整型比浮点型更易压缩,节省磁盘空间。
    • 如果比例因子不适合,则从下表选择范围小的去用:
"price": {
    "type": "scaled_float",
    "scaling_factor": 100
}

2 索引管理

2.1 搭建工程

2.1.1 ES客户端

  • ES提供多种不同的客户端:

    • TransportClient。ES提供的传统客户端,官方计划8.0版本删除此客户端。
    • RestClientRestClient是官方推荐使用的,它包括两种:Java Low Level REST ClientJava High Level REST Client
  • ES在6.0之后提供 Java High Level REST Client, 两种客户端官方更推荐使用 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>

2.1.2 配置文件application.yml

server:
  port: ${port:40100}
spring:
  application:
    name: xc-search-service
xuecheng:
  elasticsearch:
    hostlist: ${eshostlist:127.0.0.1:9200} #多个结点中间用逗号分隔

2.1.3 配置类 ElasticsearchConfig

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Administrator
 * @version 1.0
 **/
@Configuration
public class ElasticsearchConfig {

    @Value("${xuecheng.elasticsearch.hostlist}")
    private String hostlist;

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        //解析hostlist配置信息
        String[] split = hostlist.split(",");
        //创建HttpHost数组,其中存放es主机和端口的配置信息
        HttpHost[] httpHostArray = new HttpHost[split.length];
        for(int i=0;i<split.length;i++){
            String item = split[i];
            httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http");
        }
        //创建RestHighLevelClient客户端
        return new RestHighLevelClient(RestClient.builder(httpHostArray));
    }

    //项目主要使用RestHighLevelClient,对于低级的客户端暂时不用
    @Bean
    public RestClient restClient(){
        //解析hostlist配置信息
        String[] split = hostlist.split(",");
        //创建HttpHost数组,其中存放es主机和端口的配置信息
        HttpHost[] httpHostArray = new HttpHost[split.length];
        for(int i=0;i<split.length;i++){
            String item = split[i];
            httpHostArray[i] = new HttpHost(item.split(":")[0], Integer.parseInt(item.split(":")[1]), "http");
        }
        return RestClient.builder(httpHostArray).build();
    }

}

2.2 java api

2.2.1 创建索引

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex {
    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private RestClient restClient;

    //创建索引库
    @Test
    public void testCreacteIndex() throws IOException {
        //创建索引对象
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("xc_course");
        //设置参数
        createIndexRequest.settings(Settings.builder().put("number_of_shards", "1").put("number_of_replicas", "0"));
        //指定映射
        createIndexRequest.mapping("doc", "{\n" +
                "\t\"properties\": {\n" +
                "\t\t\"studymodel\": {\n" +
                "\t\t\t\"type\": \"keyword\"\n" +
                "\t\t},\n" +
                "\t\t\"name\":{\n" +
                "\t\t\t\"type\": \"keyword\"\t\n" +
                "\t\t},\n" +
                "\t\t\"description\":{\n" +
                "\t\t\t\"type\": \"text\",\t\n" +
                "\t\t\t\"analyzer\": \"ik_max_word\",\t\n" +
                "\t\t\t\"search_analyzer\": \"ik_smart\"\n" +
                "\t\t},\n" +
                "\t\t\"pic\":{\n" +
                "\t\t\t\"type\": \"text\",\n" +
                "\t\t\t\"index\": false\n" +
                "\t\t}\n" +
                "\t}\n" +
                "}", XContentType.JSON);

        //操作索引客户端
        IndicesClient indicesClient = client.indices();
        //执行创建索引库
        CreateIndexResponse createIndexResponse = indicesClient.create(createIndexRequest);
        //得到响应
        boolean isSuccess = createIndexResponse.isAcknowledged();

        System.out.println(isSuccess);
    }
}

2.2.2 删除索引

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex {
    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private RestClient restClient;
    
   //删除索引库
    @Test
    public void testDeleteIndex() throws IOException {
        //删除索引请求对象
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("xc_course");

        //删除索引(发起删除请求)
        //操作索引的客户端
        IndicesClient indicesClient = client.indices();
        //执行删除
        DeleteIndexResponse deleteIndexResponse = indicesClient.delete(deleteIndexRequest);

        //删除索引响应结果
        boolean isSuccess = deleteIndexResponse.isAcknowledged();
        System.out.println(isSuccess);
    }
}

2.2.3 添加文档

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex {
    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private RestClient restClient;

    //添加文档
    @Test
    public void testAddDoc() throws IOException {
        //准备文档
        Map<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("name", "spring cloud实战");
        jsonMap.put("description", "本课程主要从四个章节进行讲解:1.微服务架构入门。2.spring cloud 实战。3.实战spring。4.。。");
        jsonMap.put("studymodel", "201001");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        jsonMap.put("timestamp", dateFormat.format(new Date()));
        jsonMap.put("price", 5.6f);

        //创建请求
        IndexRequest indexRequest = new IndexRequest("xc_course", "doc");
        //指定文档内容
        indexRequest.source(jsonMap);
        //通过client进行http请求
        IndexResponse indexResponse = client.index(indexRequest);
        //响应结果
        DocWriteResponse.Result result = indexResponse.getResult();
        System.out.println(result);
    }
}

2.2.4 查询文档

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex {
    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private RestClient restClient;

    //查询文档
    @Test
    public void testGetDoc() throws IOException {
        //创建请求
        GetRequest getRequest = new GetRequest("xc_course", "doc", "O4dlV3AB70vpNQQ-8OJA");
        //发起请求
        GetResponse getResponse = client.get(getRequest);
        //得到文档内容
        Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
        System.out.println(sourceAsMap);
    }
}

2.2.5 更新文档

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex {
    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private RestClient restClient;

    //更新文档
    @Test
    public void testUpdateDoc() throws IOException {
        //创建请求
        UpdateRequest updateRequest = new UpdateRequest("xc_course", "doc", "O4dlV3AB70vpNQQ-8OJA");
        //待更新的内容
        Map<String, String> map = new HashMap<>();
        map.put("name", "spring cloud实战修改后");
        updateRequest.doc(map);
        //发起请求
        UpdateResponse updateResponse = client.update(updateRequest);

        RestStatus status = updateResponse.status();
        System.out.println(status);
    }
}

2.2.6 根据Id删除文档

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestIndex {
    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private RestClient restClient;

    //根据Id删除文档
    @Test
    public void testDeleteDoc() throws IOException {
        //删除文档的Id
        String id = "O4dlV3AB70vpNQQ-8OJA";

        //创建请求
        DeleteRequest deleteRequest = new DeleteRequest("xc_course", "doc", id);

        //发起请求
        DeleteResponse deleteResponse = client.delete(deleteRequest);
        //响应结果
        DocWriteResponse.Result result = deleteResponse.getResult();

        System.out.println(result);
    }
}
Last modification:February 18th, 2020 at 06:18 pm