目录:
(1)商品检索功能介绍
(2)根据业务搭建数据结构
(3)nested 介绍
(4)搭建service-list服务
(5)构建实体与es mapping建立映射关系
(6)初始化mapping结构到es中
(1)商品检索功能介绍
根据用户输入的检索条件,查询出对应的商品
检索两个入口
首页的分类:
搜索栏:
检索列表展示页面
(2)根据业务搭建数据结构
建立mapping!
这时我们要思考三个问题:
- 哪些字段需要分词
- 例如:商品名称
- 我们用哪些字段进行过滤
- 平台属性值
- 分类Id
- 哪些字段我们需要通过搜索查询出来。
- 商品名称,价格,图片等。
以上分析的所有显示,以及分词,过滤的字段都应该在es中出现。Es中如何保存这些数据呢?
“根据上述的字段描述,应该建立一个mappings对应的存上上述字段描述的信息!”
根据以上制定出如下结构:mappings
Index:goods
type:_doc
document: properties - rows
field: id,price,title…
Es中index默认是true。
注意:ik_max_word 中文词库必须有!
attrs:平台属性值的集合,主要用于平台属性值过滤。
(3)nested
介绍
nested:类型是一种特殊的对象object数据类型(specialised version of the object datatype ),允许对象数组彼此独立地进行索引和查询。
demo: 建立一个普通的index
如果linux 中有这个my_index 先删除!DELETE /my_index
步骤1:建立一个index
PUT my_index/_doc/1
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
步骤2 : 执行查询
GET my_index/_search
{
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "Smith" }}
]
}
}
}
查询结果:
能够查询出数据的原因是因为:建立my_index 的时候,它默认的数据类型是Object
{user.first:”John ,Alice”}
{user.last:”Smith,White”}
实际上:从业务的角度出发应该没有数据: 因为
User1 {John,Smith}
User2 {Alice,White}
是两个对象 而 {Alice,Smith} 在当前的user 中不存在!
步骤3:删除当前索引
DELETE /my_index
步骤4:建立一个nested 类型的
PUT my_index
{
"mappings": {
"properties": {
"user": {
"type": "nested"
}
}
}
}
user
字段映射为nested
类型,而不是默认的object
类型
重新执行步骤1,使用nested 查询
GET /my_index/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{"match": {"user.first": "Alice"}},
{"match": {"user.last": "Smith"}}
]
}
}
}
}
}
此查询得不到匹配,是因为Alice
和Smith
不在同一个嵌套对象中。
尽管查询的对象是一个,但是是nested存储,普通的查询不能查出来
{"match": {"user.last": "White"}} 此时就会有数据:
(4)搭建service-list服务
在service模块下搭建,搭建方式如service-item
修改配置pom.xml
添加依赖:
<dependencies>
<dependency>
<groupId>com.atguigu.gmall</groupId>
<artifactId>service-product-client</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
</dependencies>
说明:
- 引入service-product-client模块
- 引入spring-boot-starter-data-elasticsearch依赖
添加配置文件
bootstrap.properties:
说明:添加es配置
spring.application.name=service-list spring.profiles.active=dev spring.cloud.nacos.discovery.server-addr=192.168.200.129:8848 spring.cloud.nacos.config.server-addr=192.168.200.129:8848 spring.cloud.nacos.config.prefix=${spring.application.name} spring.cloud.nacos.config.file-extension=yaml spring.cloud.nacos.config.shared-configs[0].data-id=common.yaml
添加主启动类
没有用到mysql,这里需要用注解排除数据源
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@ComponentScan({"com.atguigu.gmall"})
@EnableDiscoveryClient
@EnableFeignClients(basePackages= {"com.atguigu.gmall"})
public class ServiceListApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceListApplication.class,args);
}
}
(5)构建实体与es mapping建立映射关系
package com.atguigu.gmall.model.list;
@Document(indexName = "goods", shards = 3, replicas = 1)
@Data
public class Goods {
@Id
private Long id;
@Field(type = FieldType.Keyword, index = false)
private String defaultImg;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;
@Field(type = FieldType.Double)
private Double price;
@Field(type = FieldType.Date,format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; // 新品
@Field(type = FieldType.Long)
private Long tmId;
@Field(type = FieldType.Keyword)
private String tmName;
@Field(type = FieldType.Keyword)
private String tmLogoUrl;
@Field(type = FieldType.Long)
private Long category1Id;
@Field(type = FieldType.Keyword)
private String category1Name;
@Field(type = FieldType.Long)
private Long category2Id;
@Field(type = FieldType.Keyword)
private String category2Name;
@Field(type = FieldType.Long)
private Long category3Id;
@Field(type = FieldType.Keyword)
private String category3Name;
@Field(type = FieldType.Long)
private Long hotScore = 0L;
@Field(type = FieldType.Nested)
private List<SearchAttr> attrs;
}
平台属性-平台属性值
@Data
public class SearchAttr {
@Field(type = FieldType.Long)
private Long attrId;
@Field(type = FieldType.Keyword)
private String attrName;
@Field(type = FieldType.Keyword)
private String attrValue;
}
(6)初始化mapping结构到es中
package com.atguigu.gmall.list.controller;
@RestController
@RequestMapping("api/list")
public class ListApiController {
@Autowired
private ElasticsearchRestTemplate restTemplate;
/**
* @return
*/
@GetMapping("inner/createIndex")
public Result createIndex() {
//创建索引库
restTemplate.createIndex(Goods.class);
//建立mapping
restTemplate.putMapping(Goods.class);
return Result.ok();
}
}
在浏览器运行:
http://localhost:8203/api/list/inner/createIndex
通过kibana查看mapping