目录:
(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-listspring.profiles.active=devspring.cloud.nacos.discovery.server-addr=192.168.200.129:8848spring.cloud.nacos.config.server-addr=192.168.200.129:8848spring.cloud.nacos.config.prefix=${spring.application.name}spring.cloud.nacos.config.file-extension=yamlspring.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 {@Idprivate 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 {@Autowiredprivate ElasticsearchRestTemplate restTemplate;/*** @return*/@GetMapping("inner/createIndex")public Result createIndex() {//创建索引库restTemplate.createIndex(Goods.class);//建立mappingrestTemplate.putMapping(Goods.class);return Result.ok();}
}
在浏览器运行:
http://localhost:8203/api/list/inner/createIndex
通过kibana查看mapping