首先elasticsearch是面向文档(Document)存储的,可以是数据库中的一条商品数据,一个订单信息。文档数据会被序列化为json格式后存储在elasticsearch中:
而Json文档中往往包含很多的字段(Field),类似于数据库中的列。
mysql与elasticsearch
我们统一的把mysql与elasticsearch的概念做一下对比:
MySQL | Elasticsearch | 说明 |
Table | Index | 索引(index),就是文档的集合,类似数据库的表(table) |
Row | Document | 文档(Document),就是一条条的数据,类似数据库中的行(Row),文档都是JSON格式 |
Column | Field | 字段(Field),就是JSON文档中的字段,类似数据库中的列(Column) |
Schema | Mapping | Mapping(映射)是索引中文档的约束,例如字段类型约束。类似数据库的表结构(Schema) |
SQL | DSL | DSL是elasticsearch提供的JSON风格的请求语句,用来操作elasticsearch,实现CRUD |
下面的开始实现把MySql中的语句导入ElasticSearch中
1、分析在ElasticSearch中需要建立的索引所包含的字段
其中suggestion字段是一个集合,包括品牌名称、商品分类,这个字段是我们到时候要在搜索框中进行联想查询的字段,例如输入小字,就会进行联想到小米以及其他例如小红书、小说等等。
1.1、通过图形化界面kibana 去连接我们的elasticSearch进行建索引操作,也就是我们数据库中的表,这里就不介绍elasticSearch和kibana7.12.1是怎么安装的了。
1.2构建索引hmall
PUT /hmall
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer":{
"tokenizer":"ik_max_word",
"filter":"py"
},
"completion_analyzer":{
"tokenizer":"keyword",
"filter":"py"
}
},
"filter": {
"py":{
"type":"pinyin",
"keep_full_pingyin":false,
"keep_joined_full_pinyin":true,
"keep_original":true,
"limit_first_letter_length":16,
"remove_duplicated_term":true,
"none_chinese_pinyin_tokenize":false
}
}
}
},
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"name":{
"type": "text",
"analyzer": "ik_max_word",
"copy_to": "all"
},
"price":{
"type": "long"
},
"image":{
"type": "keyword",
"index": false
}
,
"category":{
"type": "keyword",
"copy_to": "all"
},
"brand":{
"type": "keyword",
"copy_to": "all"
},
"sold":{
"type": "integer"
},
"commentCount":{
"type": "integer"
},
"status":{
"type": "integer"
},
"isAD":{
"type": "boolean"
},
"all":{
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"suggestion":{
"type": "completion",
"analyzer": "completion_analyzer"
}
}
}
}
2、初始化RestClient
在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。
分为三步:
2.1、引入es的RestHighLevelClient依赖:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
2.2、因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本:
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
2.3、初始化RestHighLevelClient:
初始化的代码如下:
@Configuration
public class EsConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
return new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.153.144:9200")));
}
}
3、elasticService服务要读取商品信息到elasticSearch中,那么就需要调用itemService服务把MySql中item表中的信息读取出来,这里我们服务与服务之间的调用是通过Feign来实现的,具体怎么实现,在我的另外一篇文章中有所介绍。
链接: Feign的使用.
3.1、定义一个对象RestHighLevelClient交给容器去管理,该对象是用来访问elaticSearch的。
我们可以使用RestHighLevelClient对象去操作elasticSearch的Api。
三、在测试类通过Api复制数据
源代码:
@SpringBootTest
public class EsTest {
@Autowired
private RestHighLevelClient client;
@Autowired
private ItemClient itemClient;
final ObjectMapper objectMapper = new ObjectMapper();
@Test
public void testImport() throws IOException {
int i = 1;
while (true) {
//调用feign 去itemservice中查询数据
final PageDTO<Item> itemPageDTO = itemClient.queryByPage(i, 500);
final List<Item> list = itemPageDTO.getList();
if (list.size()<=0){
break;
}
final BulkRequest bulkRequest = new BulkRequest();
for (Item item : list) {
final ItemDoc doc = new ItemDoc();
BeanUtils.copyProperties(item, doc);
doc.setSuggestion(Arrays.asList(doc.getBrand(), item.getCategory()));
final IndexRequest hmall = new IndexRequest("hmall").id(doc.getId() + "");
hmall.source(objectMapper.writeValueAsString(doc), XContentType.JSON);
bulkRequest.add(hmall);
}
//利用restHight
client.bulk(bulkRequest, RequestOptions.DEFAULT);
i++;
}
}
}