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
"中,一般情况下不需要设置store
为true
,因为在_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版本删除此客户端。RestClient
。RestClient
是官方推荐使用的,它包括两种:Java Low Level REST Client
和Java 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);
}
}