WM_技术中台下终搜的技术解决方案-stage2 通过DQL实现es相关功能 暂时没用

服务(应用)名称
Docker容器地址
端口
查询服务
172.188.0.33
8888
分析服务
172.188.0.34
5555
网关服务
172.188.0.22
6666
logstash
172.188.0.77
9600
kinana
172.188.0.66
5601
msyql
172.188.0.55
33066
nacos1
nacos:8848
8848-->8848
nacos2
nacos:8848
8848-->8849
nacos3
nacos:8848
8848-->8850
nacos-server-mysql
mysql:3306
3306
prometheus
172.188.0.11
9090
grafana
172.188.0.12
3000
eNode1
172.188.0.88
9200 / 9700
eNode2
172.188.0.89
9201 / 9800
eNode3
172.188.0.90
9202 / 9900
日志埋点与落盘
172.188.0.77
TCP 4567
链路追踪
172.188.0.99
9411
1 语言处理与自动补全技术探测
实现的效果
实现的最终效果如下图京东搜索相似,输入词的时候返回提示。同时输入拼音和首字母也会有相同的提示
效果
输入汉字
+微信study322
专业一手超清完整
全网课程 超低价格输入拼音
输入首字母
2.1 自定义语料库
+微信study322
专业一手超清完整
全网课程 超低价格2.1.1 语料库映射OpenAPI
索引映射OpenAPI
1、定义索引(映射)接口
2、定义索引(映射)实现
package com.itheima.service;
import com.it
he
im
a
.
co
m
m
o
n
s
.p
o
j
o
.C
o
m
m
o
n
En
t
ity;
import org.el
a
st
i
cs
e
a
r
c
h
.
re
s
t
.
Re
s
t
S
t
at
u
s
;
import jav
a
.
u
t
i
l
.
L
i
st
;
import jav
a
.
u
t
i
l
.M
a
p
;
/**
* @Class: ElasticsearchIndexService
* @Package com.itheima.service
* @Description: 索引操作接口
* @Company: http://www.itheima.com/
*/
public interface ElasticsearchIndexService {
//新增索引+映射
boolean addIndexAndMapping(CommonEntity commonEntity) throws Exception;
}
/*
* @Description: 新增索引+setting+映射+自定义分词器pinyin
* setting可以为空(自定义分词器pinyin在setting中)
* 映射可以为空
* @Method: addIndexAndMapping
* @Param: [commonEntity]
* @Update:
* @since: 1.0.0
* @Return: boolean
*
*/
public boolean addIndexAndMapping(CommonEntity commonEntity) throws
Exception {
//设置setting的map
Map<String, Object> settingMap = new HashMap<String, Object>();
//创建索引请求
CreateIndexRequest request = new
CreateIndexRequest(commonEntity.getIndexName());
//获取前端参数
Map<String, Object> map = commonEntity.getMap();
//循环外层的settings和mapping
for (Map.Entry<String, Object> entry : map.entrySet()) {
if ("settings".equals(entry.getKey())) {
if (entry.getValue() instanceof Map && ((Map)
entry.getValue()).size() > 0) {
request.settings((Map<String, Object>) entry.getValue());
+微信study322
专业一手超清完整
全网课程 超低价格3、新增控制器
}
}
if ("mapping".equals(entry.getKey())) {
if (entry.getValue() instanceof Map && ((Map)
entry.getValue()).size() > 0) {
request.mapping((Map<String, Object>) entry.getValue());
}
}
}
//创建
索引操作客户端
I
n
di
ce
s
Cl
ie
nt indices = client.indices();
//
C
r
e
a
t
e
I
nd
e
x
Re
s
po
nse response = indices.create(request,
RequestO
pt
io
n
s
.
D
E
FA
U
LT
)
;
//
return response.isAcknowledged();
}
/*
* @Description: 新增索引、映射
* @Method: addIndex
* @Param: [commonEntity]java
* @Update:
* @since: 1.0.0
* @Return: com.itheima.commons.result.ResponseData
*
*/
@PostMapping(value = "/add")
public ResponseData addIndexAndMapping(@RequestBody CommonEntity
commonEntity) {
//构造返回数据
ResponseData rData = new ResponseData();
if (StringUtils.isEmpty(commonEntity.getIndexName())) {
rData.setResultEnum(ResultEnum.param_isnull);
return rData;
}
//增加索引是否成功
boolean isSuccess = false;
try {
//通过高阶API调用增加索引方法
isSuccess =
elasticsearchIndexService.addIndexAndMapping(commonEntity );
//构建返回信息通过类型推断自动装箱(多个参数取交集)
rData.setResultEnum(isSuccess, ResultEnum.success, 1);
//日志记录
logger.info(TipsEnum.create_index_success.getMessage());
} catch (Exception e) {
//打印到控制台
e.printStackTrace();
//日志记录
logger.error(TipsEnum.create_index_fail.getMessage(), e);
//构建错误返回信息
rData.setResultEnum(ResultEnum.error);
+微信study322
专业一手超清完整
全网课程 超低价格4.开始新增映射
参数
自定义分词器ik_pinyin_analyzer(
ik和pinyin组合分词器)
tips
在创建映射前,需要安装拼音插件
}
return rData;
}
http://172.17.0.225:8888/v1/indices/add
或者
http://127.0.
0.1:8888/v1/indices/add
{
"indexName": "product_completion_index",
"map": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 2,
"analysis": {
"analyzer": {
"ik_pinyin_analyzer": {
"type": "custom",
"tokenizer": "ik_smart",
"filter": "pinyin_filter"
}
},
"filter": {
"pinyin_filter": {
"type": "pinyin",
"keep_first_letter": true,
"keep_separate_first_letter": false,
"keep_full_pinyin": true,
"keep_original": true,
"limit_first_letter_length": 16,
"lowercase": true,
"remove_duplicated_term": true
}
}
}
},
"mapping": {
"properties": {
"name": {
"type": "keyword"
},
"searchkey": {
"type": "completion",
"analyzer": "ik_pinyin_analyzer"
}
}
}
+微信study322
专业一手超清完整
全网课程 超低价格属性
说明
keep_fifirst_letter
启用此选项时,例如:刘德华> ldh,默认值:
true
keep_separate_fifirst_letter
启用该选项时,将保留第一个字母分开,例如:
刘德华> l,d,h,默认:假的,注意:查询结果
也许是太模糊,由于长期过频
limit_fifirst_letter_length
设置fifirst_letter结果的最大长度,默认值:16
settings下面的为索引的设置信息,动态设置参数,遵循DSL写法
mapping下为映射
的字段信息,动态设置参数,遵循DSL写法
}
}
+微信study322
专业一手超清完整
全网课程 超低价格属性
说明
keep_full_pinyin
当启用该选项,例如:刘德华> [ liu,de,
hua],默认值:true
keep_joined_full_pinyin
当启用此选项时,例如:刘德华> [ liudehua],
默认值:false
keep_none_ch
inese
果中
中文
tr
u
e
keep_none
_chinese_together
认值
:t
ru
e
,如
:D
J音
-
>
D
J,
y
in,
y
u
e
j
ia
f
al
se
,例
D
J音
-
>
D
J
y
in
yu
e
,j
ia
:k
ee
p
_n
o
ne
_c
h
in
e
se
须先启动
keep_none_chinese_in_fifirst_letter
第一个字母保持非中文字母,例如:刘德华
AT2016- > ldhat2016,默认值:true
keep_none_chinese_in_joined_full_pinyin
保留非中文字母加入完整拼音,例如:刘德华
2016- > liudehua2016,默认:false
none_chinese_pinyin_tokenize
打破非中国信成单独的拼音项,如果他们拼音,
默认值:true,如:
liudehuaaɹ ibaba13zhuanghan- > liu,de,
hua,a,li,ba,ba,13,zhuang,han,注
意:keep_none_chinese和
keep_none_chinese_together应首先启用
keep_original
当启用此选项时,也会保留原始输入,默认值:
false
lowercase
小写非中文字母,默认值:true
trim_whitespace
默认值:true
remove_duplicated_term
当启用此选项时,将删除重复项以保存索引,例
如:de的> de,默认值:false,注意:位置相关
查询可能受影响
返回
2.1.2 语料库文档OpenAPI
1、定义批量新增文档接口
{
"code": "200",
"desc": "操作成功!",
"data": true
}
package com.itheima.service;
+微信study322
专业一手超清完整
全网课程 超低价格2、定义批量新增文档实现
import com.itheima.commons.pojo.CommonEntity;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import java.util.List;
import java.u
til.Map;
/**
* @Class
: ElasticsearchDocumentService
* @Pack
a
g
e
c
o
m
.
i
th
ei
m
a.
se
rvice
* @Desc
r
i
p
t
i
o
n
:
* @Company: http://www.itheima.com/
*/
public interface ElasticsearchDocumentService {
//批量新增文档
public RestStatus bulkAddDoc(CommonEntity commonEntity) throws Exception;
}
/*
* @Description: 批量新增文档,可自动创建索引、自动创建映射
* @Method: bulkAddDoc
* @Param: [indexName, map]
* @Update:
* @since: 1.0.0
* @Return: org.elasticsearch.rest.RestStatus
*
*/
@Override
public RestStatus bulkAddDoc(CommonEntity commonEntity) throws Exception {
//通过索引构建批量请求对象
BulkRequest bulkRequest = new BulkRequest(commonEntity.getIndexName());
//循环前台list文档数据
for (int i = 0; i < commonEntity.getList().size(); i++) {
bulkRequest.add(new IndexRequest().source(XContentType.JSON,
SearchTools.mapToObjectGroup(commonEntity.getList().get(i))));
}
//执行批量新增
BulkResponse bulkResponse = client.bulk(bulkRequest,
RequestOptions.DEFAULT);
return bulkResponse.status();
}
+微信study322
专业一手超清完整
全网课程 超低价格官方文档介绍https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.4/java-rest-high
-document-bulk.html
+微信study322
专业一手超清完整
全网课程 超低价格
如上图,需要定义成箭头中的形式
所以上面SearchTools.mapToObjectGroup将map转成了数组
3、定义批量新增文档控制器
/*
* @Description: 批量新增文档,可自动创建索引、自动创建映射
* @Method: bulkAddDoc
* @Param: [indexName, map]
* @Update:
* @since: 1.0.0
* @Return: org.elasticsearch.rest.RestStatus
*
*/
@PostMapping(value = "/batch")
public ResponseData bulkAddDoc(@RequestBody CommonEntity commonEntity) {
//构造返回数据
ResponseData rData = new ResponseData();
if (StringUtils.isEmpty(commonEntity.getIndexName()) ||
CollectionUtils.isEmpty(commonEntity.getList())) {
rData.setResultEnum(ResultEnum.param_isnull);
return rData;
}4、开始批量新增调用
参数
定义23个suggest词库(定义了两个小米手机,验证是否去重)
tips
学完聚合通过日志埋点、数据落盘进行维护
//批量新增操作返回结果
RestStatus result = null;
try {
//通过高阶API调用批量新增操作方法
result = elasticsearchDocumentService.bulkAddDoc(commonEntity);
//通过类型推断自动装箱(多个参数取交集)
rData.setResultEnum(result, ResultEnum.success, null);
//日志记录
logger.info(TipsEnum.batch_create_doc_success.getMessage());
} cat
c
h
(E
x
ce
pt
ion e) {
/
/
e
.p
r
in
t
StackTrace();
/
/
l
o
gg
er
.
in
fo
(T
i
psEnum.batch_create_doc_fail.getMessage());
/
/
rData.setResultEnum(ResultEnum.error);
}
return rData;
}
http://172.17.0.225:8888/v1/docs/batch
或者
http://127.0.0.1:8888/v1/docs/batch
{
"indexName": "product_completion_index",
"list": [
{
"searchkey": "小米手机",
"name": "小米(MI)"
},
{
"searchkey": "小米10",
"name": "小米(MI)"
},
{
"searchkey": "小米电视",
"name": "小米(MI)"
},
{
"searchkey": "小米路由器",
"name": "小米(MI)"
},
{
+微信study322
专业一手超清完整
全网课程 超低价格"searchkey": "小米9",
"name": "小米(MI)"
},
{
"searchkey": "小米手机",
"name": "小米(MI)"
},
{
"searchkey": "小米耳环",
"
name": "小米(MI)"
},
{
"searchkey": "小米8",
"name": "小米(MI)"
}
,
{
"searchkey": "小米10Pro",
"name": "小米(MI)"
},
{
"searchkey": "小米笔记本",
"name": "小米(MI)"
},
{
"searchkey": "小米摄像头",
"name": "小米(MI)"
},
{
"searchkey": "小米电饭煲",
"name": "小米(MI)"
},
{
"searchkey": "小米充电宝",
"name": "小米(MI)"
},
{
"searchkey": "adidas男鞋",
"name": "adidas男鞋"
},
{
"searchkey": "adidas女鞋",
"name": "adidas女鞋"
},
{
"searchkey": "adidas外套",
"name": "adidas外套"
},
{
"searchkey": "adidas裤子",
"name": "adidas裤子"
},
{
"searchkey": "adidas官方旗舰店",
"name": "adidas官方旗舰店"
},
{
"searchkey": "阿迪达斯袜子",
+微信study322
专业一手超清完整
全网课程 超低价格返回
查看
2.2产品搜索与自动补全
"name": "阿迪达斯袜子"
},
{
"searchkey": "阿迪达斯外套",
"name": "阿迪达斯外套"
},
{
"searchkey": "阿迪达斯运动鞋",
"
name": "阿迪达斯运动鞋"
},
{
"searchkey": "耐克外套",
"name": "耐克外套"
}
,
{
"searchkey": "耐克运动鞋",
"name": "耐克运动鞋"
}
]
}
{
"code": "200",
"desc": "操作成功!",
"data": "OK"
}
GET product_completion_index/_search
+微信study322
专业一手超清完整
全网课程 超低价格Term suggester :词条建议器。对给输入的文本进进行分词,为每个分词提供词项建议
Phrase suggester :短语建议器,在term的基础上,会考量多个term之间的关系
Completion Suggester,它主要针对的应用场景就是"Auto Completion"。
Context Suggester:上下文建议器
2.2.1 汉字补全OpenAPI
1、定义自动补全接口
GET produc
t_completion_index/_search
{
"from"
:
0
,
"size"
:
10
0,
"suggest": {
"czbk-suggest": {
"prefix": "小米",
"completion": {
"field": "searchkey",
"size": 20,
"skip_duplicates": true
}
}
}
}
package com.itheima.service;
import com.itheima.commons.pojo.CommonEntity;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import java.util.List;
import java.util.Map;
/**
* @Class: ElasticsearchDocumentService
* @Package com.itheima.service
* @Description: 文档操作接口
* @Company: http://www.itheima.com/
*/
public interface ElasticsearchDocumentService {
//自动补全(完成建议)
public List<String> cSuggest(CommonEntity commonEntity) throws Exception;
+微信study322
专业一手超清完整
全网课程 超低价格2、定义自动补全实现
}
/*
* @Description: 自动补全 根据用户的输入联想到可能的词或者短语
* @Me
t
h
od
:
s
u
g
g
e
st
e
r
* @Pa
ra
m
:
[c
o
m
m
o
n
E
nt
ity]
* @
U
pd
a
t
e
:
* @
si
n
c
e
:
1.0.0
* @Return: org.elasticsearch.action.search.SearchResponse
*
*/
public List<String> cSuggest(CommonEntity commonEntity) throws Exception {
//定义返回
List<String> suggestList = new ArrayList<>();
//构造搜索建议语句,搜索条件字段
CompletionSuggestionBuilder completionSuggestionBuilder =
SuggestBuilders.completionSuggestion(commonEntity.getSuggestFileld());
//搜索关键字
completionSuggestionBuilder.prefix(commonEntity.getSuggestValue());
//去除重复
completionSuggestionBuilder.skipDuplicates(true);
//匹配数量
completionSuggestionBuilder.size(commonEntity.getSuggestCount());
//czbk-suggest为返回的字段,所有返回将在czbk-suggest里面,可写死,sort按照评分排
SearchRequest searchRequest = new
SearchRequest().indices(commonEntity.getIndexName()).source(new
SearchSourceBuilder().sort(new
ScoreSortBuilder().order(SortOrder.DESC)).suggest(
new SuggestBuilder().addSuggestion("czbk-suggest",
completionSuggestionBuilder)
));
//定义查找响应
SearchResponse suggestResponse = client.search(searchRequest,
RequestOptions.DEFAULT);
//定义完成建议对象
CompletionSuggestion completionSuggestion =
suggestResponse.getSuggest().getSuggestion("czbk-suggest");
//获取返回数据
List<CompletionSuggestion.Entry.Option> optionsList =
completionSuggestion.getEntries().get(0).getOptions();
//从optionsList取出结果
if (!CollectionUtils.isEmpty(optionsList)) {
optionsList.forEach(item -> {
suggestList.add(item.getText().string());
});
}
return suggestList;
}
+微信study322
专业一手超清完整
全网课程 超低价格3、定义自动补全控制器
4、自动补全调用验证
参数
/*
* @Description 自动补全
* @Metho
d
:
s
u
g
g
e
st
e
r
* @Param
:
[c
o
m
m
o
n
E
nt
ity]
* @Update:
* @s
i
nc
e
:
1
.
0
.0
* @Re
t
u
rn
:
c
o
m
.itheima.commons.result.ResponseData
*
*/
@GetMapping(value = "/csuggest")
public ResponseData cSuggest(@RequestBody CommonEntity commonEntity) {
// 构造返回数据
ResponseData rData = new ResponseData();
if (StringUtils.isEmpty(commonEntity.getIndexName()) ||
StringUtils.isEmpty(commonEntity.getSuggestFileld()) ||
StringUtils.isEmpty(commonEntity.getSuggestValue())) {
rData.setResultEnum(ResultEnum.param_isnull);
return rData;
}
//批量查询返回结果
List<String> result = null;
try {
//通过高阶API调用批量新增操作方法
result = elasticsearchDocumentService.cSuggest(commonEntity);
//通过类型推断自动装箱(多个参数取交集)
rData.setResultEnum(result, ResultEnum.success, result.size());
//日志记录
logger.info(TipsEnum.csuggest_get_doc_success.getMessage());
} catch (Exception e) {
//打印到控制台
e.printStackTrace();
//日志记录
logger.error(TipsEnum.csuggest_get_doc_fail.getMessage());
//构建错误返回信息
rData.setResultEnum(ResultEnum.error);
}
return rData;
}
http://172.7.0.225:6666/v1/docs/csuggest
+微信study322
专业一手超清完整
全网课程 超低价格indexName索引名称
suggestFileld:自
动补全查找列
suggestValue
:自动补全输入的关键字
suggestCount:自动补全返回个数(京东是13个)
返回
自动补全自动去重
2.2.2 拼音补全OpenAPI
使用拼音访问【小米】
{
"indexName": "product_completion_index",
"suggestFileld": "searchkey",
"suggestValue": "小米",
"suggestCount": 13
}
{
"code": "200",
"desc": "操作成功!",
"data": [
"小米10",
"小米10Pro",
"小米8",
"小米9",
"小米充电宝",
"小米手机",
"小米摄像头",
"小米电视",
"小米电饭煲",
"小米笔记本",
"小米耳环",
"小米路由器"
],
"count": 12
}
http://localhost:8888/v1/docs/csuggest
全拼访问
{
"indexName": "product_completion_index",
"suggestFileld": "searchkey",
"suggestValue": "xiaomi",
"suggestCount": 13
}
+微信study322
专业一手超清完整
全网课程 超低价格1、下载拼插件
当我们创建索引时可以自定义分词器,通过指定映射去匹配自定义分词器
全拼访问(分隔)
{
"indexName": "product_completion_index",
"suggestFileld": "searchkey",
"suggestValue": "xiao mi",
"suggestCount": 13
}
首字母访问
{
"index
Name": "product_completion_index",
"sug
g
e
s
t
F
il
e
ld
"
:
"
se
a
rchkey",
"sug
g
e
s
tV
a
l
ue
"
:
"x
m
"
,
"suggestCount": 13
}
wget https://github.com/medcl/elasticsearch-analysis
pinyin/releases/download/v7.4.0/elasticsearch-analysis-pinyin-7.4.0.zip
或者
https://github.com/medcl/elasticsearch-analysis-pinyin/releases/tag/v7.4.0
+微信study322
专业一手超清完整
全网课程 超低价格调用【新增文档开发API】接口进行新增数据
开始拼音补全
{
"indexName": "product_completion_index",
"map": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 2,
"analysis": {
"analyzer": {
"
i
k_
p
i
ny
in
_
an
a
l
y
z
e
r"
:
{
"t
y
pe
"
:
"
c
u
st
o
m
"
,
"tokenizer": "ik_smart",
"filter": "pinyin_filter"
}
}
,
"f
ilter": {
"pinyin_filter": {
"type": "pinyin",
"keep_first_letter": true,
"keep_separate_first_letter": false,
"keep_full_pinyin": true,
"keep_original": true,
"limit_first_letter_length": 16,
"lowercase": true,
"remove_duplicated_term": true
}
}
}
},
"mapping": {
"properties": {
"name": {
"type": "text"
},
"searchkey": {
"type": "completion",
"analyzer": "ik_pinyin_analyzer"
}
}
}
}
}
+微信study322
专业一手超清完整
全网课程 超低价格2.3 产品搜索与语言处理
2.3.1 什么是语言处理(拼写纠错)
场景描述
例如:错误输入"【adidaas官方旗舰店】 ”能够纠错为【adidas官方旗舰店】
+微信study322
专业一手超清完整
全网课程 超低价格2.3.2 语
言处理OpenAPI
1、定义拼写纠错接口
2、定义拼写纠错实现
GET product_completion_index/_search
{
"suggest": {
"czbk-suggestion": {
"text": "adidaas官方旗舰店",
"phrase": {
"field": "name",
"size": 13
}
}
}
}
//拼写纠错
public String pSuggest(CommonEntity commonEntity) throws Exception;
/*
* @Description: 拼写纠错
* @Method: psuggest
* @Param: [commonEntity]
* @Update:
* @since: 1.0.0
* @Return: java.util.List<java.lang.String>
*
*/
@Override
public String pSuggest(CommonEntity commonEntity) throws Exception {
//定义返回
String pSuggestString = new String();
//构造短语建议器对象(参数为匹配列)
+微信study322
专业一手超清完整
全网课程 超低价格3、定义拼写纠错控制器
PhraseSuggestionBuilder pSuggestionBuilder = new
PhraseSuggestionBuilder(commonEntity.getSuggestFileld());
//搜索关键字(被纠错的值)
pSuggestionBuilder.text(commonEntity.getSuggestValue());
//匹配数量
pSuggestionBuilder.size(1);
//czbk-suggest为返回的字段,所有返回将在czbk-suggest里面,可写死,sort按照评分排
SearchRequest searchRequest = new
SearchRequest
()
.
i
nd
i
ce
s
(c
o
m
m
o
n
Entity.getIndexName()).source(new
SearchSourceB
u
il
d
e
r
()
.
so
r
t
(
n
ew
ScoreSort
B
u
i
l
d
e
r
(
)
.
o
rd
e
r
(S
o
rt
O
rd
e
r
.D
E
SC
))
.
s
ug
g
e
s
t
(
n
e
w
S
ug
g
e
s
tB
u
il
d
e
r(
)
.a
dd
Su
g
g
e
st
i
o
n
("czbk-suggest",
pSuggest
io
n
Builder)
)
)
;
//定义查找响应
SearchResponse suggestResponse = client.search(searchRequest,
RequestOptions.DEFAULT);
//定义短语建议对象
PhraseSuggestion phraseSuggestion =
suggestResponse.getSuggest().getSuggestion("czbk-suggest");
//获取返回数据
List<PhraseSuggestion.Entry.Option> optionsList =
phraseSuggestion.getEntries().get(0).getOptions();
//从optionsList取出结果
if (!CollectionUtils.isEmpty(optionsList)) {
pSuggestString = optionsList.get(0).getText().string();
}
return pSuggestString;
}
/*
* @Description: 拼写纠错
* @Method: suggester2
* @Param: [commonEntity]
* @Update:
* @since: 1.0.0
* @Return: com.itheima.commons.result.ResponseData
*
*/
@GetMapping(value = "/psuggest")
public ResponseData pSuggest(@RequestBody CommonEntity commonEntity) {
// 构造返回数据
ResponseData rData = new ResponseData();
if (StringUtils.isEmpty(commonEntity.getIndexName()) ||
StringUtils.isEmpty(commonEntity.getSuggestFileld()) ||
StringUtils.isEmpty(commonEntity.getSuggestValue())) {
rData.setResultEnum(ResultEnum.param_isnull);
return rData;
}
//批量查询返回结果
String result = null;
+微信study322
专业一手超清完整
全网课程 超低价格4、语言处理调用验证
参数
indexName索引名称
suggestFileld:自动补全查找列
suggestValue:自动补全输入的关键字
返回
2.4 总结
1. 需要一个搜索词库/语料库,不要和业务索引库在一起,方便维护和升级语料库
2. 根据分词及其他搜索条件去语料库中查询若干条(京东13条、淘宝(天猫)10条、百度4条)记录
返回
3. 为了提升准确率,通常都是前缀搜索
try {
//通过高阶API调用批量新增操作方法
result = elasticsearchDocumentService.pSuggest(commonEntity);
//通过类型推断自动装箱(多个参数取交集)
rData.setResultEnum(result, ResultEnum.success, null);
//日志记录
logger.info(TipsEnum.psuggest_get_doc_success.getMessage());
} catch (Exception e) {
//打印到控制台
e
.p
r
in
t
StackTrace();
/
/
l
o
gg
er
.
er
ro
r
(T
ipsEnum.psuggest_get_doc_fail.getMessage());
/
/
rData.setResultEnum(ResultEnum.error);
}
return rData;
}
http://172.17.0.225:6666/v1/docs/psuggest
{
"indexName": "product_completion_index",
"suggestFileld": "name",
"suggestValue": "adidaas官方旗舰店"
}
{
"code": "200",
"desc": "操作成功!",
"data": "adidas官方旗舰店"
}
+微信study322
专业一手超清完整
全网课程 超低价格2 电商平台产品推荐
2.1 什么是搜索推荐
例如:关键词输入【阿迪达斯 耐克 外套 运动鞋 袜子】
2.2 产品推荐OpenAPI
注意的地方,查看官网
https://www.elastic.co/guide/en/elasticsearch/reference/7.4/search-suggesters.html#te
rm-suggester
汪~没有找到与“阿迪达斯 耐克 外套 运动鞋 袜子”相关的商品,为您推荐“ 阿迪达斯耐克运动鞋”的相关商
品,或者试试:
GET product_completion_index/_search
{
"suggest": {
"czbk-suggestion": {
"text": "阿迪达斯 耐克 外套 运动鞋 袜子",
"term": {
"field": "name",
"min_word_length": 2,
"string_distance": "ngram",
"analyzer": "ik_smart"
}
}
}
}
+微信study322
专业一手超清完整
全网课程 超低价格+微信study322
专业一手超清完整
全网课程 超低价格
1、定义搜索推荐接口
package com.itheima.service;
import com.itheima.commons.pojo.CommonEntity;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import java.util.List;
import java.util.Map;
/**
* @Class: ElasticsearchDocumentService
* @Package com.itheima.service
* @Description: 文档操作接口2、定义搜索推
荐实现
* @Company: http://www.itheima.com/
*/
public interface ElasticsearchDocumentService {
//搜索推荐(当输入的关键词过多的时候系统进行推荐)
public String tSuggest(CommonEntity commonEntity) throws Exception;
}
/*
* @
Description: 搜索推荐(当输入的关键词过多的时候系统进行推荐)
* @Method: tSuggest
* @Param: [commonEntity]
* @Update:
* @since: 1.0.0
* @Return: java.util.List<java.lang.String>
*
*/
public String tSuggest(CommonEntity commonEntity) throws Exception {
//定义返回
String tSuggestString = new String();
//构造词条建议语句,搜索条件字段
TermSuggestionBuilder termSuggestiontextBuilder =
SuggestBuilders.termSuggestion(commonEntity.getSuggestFileld());
//搜索关键字
termSuggestiontextBuilder.text(commonEntity.getSuggestValue());
//匹配数量
// termSuggestiontextBuilder.size(commonEntity.getSuggestCount());
//输入的建议词分词
termSuggestiontextBuilder.analyzer("ik_smart");
//建议文本术语必须包含的最小长度。默认值为4。(旧名称“ min_word_len”已弃用)
termSuggestiontextBuilder.minWordLength(2);
//用于比较建议术语的相似程度的字符串距离实现
termSuggestiontextBuilder.stringDistance(TermSuggestionBuilder.StringDistanceImp
l.NGRAM);
//czbk-suggest为返回的字段,所有返回将在czbk-suggest里面,可写死,sort按照评分排
SearchRequest searchRequest = new
SearchRequest().indices(commonEntity.getIndexName()).source(new
SearchSourceBuilder().sort(new
ScoreSortBuilder().order(SortOrder.DESC)).suggest(
new SuggestBuilder().addSuggestion("czbk-suggest",
termSuggestiontextBuilder)
));
//定义查找响应
SearchResponse suggestResponse = client.search(searchRequest,
RequestOptions.DEFAULT);
//定义完成建议对象
TermSuggestion termSuggestion =
suggestResponse.getSuggest().getSuggestion("czbk-suggest");
//获取返回数据
+微信study322
专业一手超清完整
全网课程 超低价格3、定义搜索推荐控
制器
4、语言处理调用验证
参数
List<TermSuggestion.Entry.Option> optionsList =
termSuggestion.getEntries().get(0).getOptions();
//从optionsList取出结果
if (!CollectionUtils.isEmpty(optionsList)) {
tSuggestString = optionsList.get(0).getText().toString();
}
return tSuggestString;
}
/*
* @Description: 搜索推荐(当输入的关键词过多的时候系统进行推荐)
* @
M
et
h
od
:
t
S
u
g
ge
s
t
* @
Pa
ra
m
:
[
co
m
m
o
n
E
ntity]
* @Update:
* @since: 1.0.0
* @Return: com.itheima.commons.result.ResponseData
*
*/
@GetMapping(value = "/tsuggest")
public ResponseData tSuggest(@RequestBody CommonEntity commonEntity) {
// 构造返回数据
ResponseData rData = new ResponseData();
if (StringUtils.isEmpty(commonEntity.getIndexName()) ||
StringUtils.isEmpty(commonEntity.getSuggestFileld()) ||
StringUtils.isEmpty(commonEntity.getSuggestValue())) {
rData.setResultEnum(ResultEnum.param_isnull);
return rData;
}
//批量查询返回结果
String result = null;
try {
//通过高阶API调用批量新增操作方法
result = elasticsearchDocumentService.tSuggest(commonEntity);
//通过类型推断自动装箱(多个参数取交集)
rData.setResultEnum(result, ResultEnum.success, null);
//日志记录
logger.info(TipsEnum.tsuggest_get_doc_success.getMessage());
} catch (Exception e) {
//打印到控制台
e.printStackTrace();
//日志记录
logger.error(TipsEnum.tsuggest_get_doc_fail.getMessage());
//构建错误返回信息
rData.setResultEnum(ResultEnum.error);
}
return rData;
}
http://127.0.0.1:8888/v1/docs/tsuggest
+微信study322
专业一手超清完整
全网课程 超低价格indexName索引名称
suggestFileld:自
suggestValue:自
的关键字
返回
3 指标聚合与下钻分析
3.1 指标聚合与分类
什么是指标聚合(Metric)
聚合分析是数据库中重要的功能特性,完成对某个查询的数据集中数据的聚合计算,
如:找出某字段(或计算表达式的结果)的最大值、最小值,计算和、平均值等。
ES作为搜索引擎兼数据库,同样提供了强大的聚合分析能力。
对一个数据集求最大值、最小值,计算和、平均值等指标的聚合,在ES中称为指标聚合。
Metric聚合分析分为单值分析和多值分析两类
1、单值分析,只输出一个分析结果
min,max,avg,sum,cardinality(
cardinality 求唯一值,即不重复的字段有多少(相当于mysql中的
distinct)
2、多值分析,输出多个分析结果
stats,extended_stats,percentile,percentile_rank
3.2 指标聚合与下钻设计
官网:https://www.elastic.co/guide/en/elasticsearch/reference/7.4/search-aggregations-metr
ics.html
语法:
{
"indexName": "product_completion_index",
"suggestFileld": "name",
"suggestValue": "阿迪达斯 耐克 外套 运动鞋 袜子"
}
{
"code": "200",
"desc": "操作成功!",
"data": "阿迪达斯外套"
}
+微信study322
专业一手超清完整
全网课程 超低价格openAPI设计目标与原则:
1、DSL调用与语法进行高度抽象,参数动态设计
2、Open API通过结果转换器支持上百种组合调用
qurey,constant_score,match/matchall/fifilter/sort/size/frm/higthlight/_source/includes
3、逻辑处理公共调用,提升API业务处理能力
4、保留原生API与参数的用法
3.2.1 基础框架搭建
tips:confifig class
3.2.2 单值分析API设计
1、Avg(平均值)
从聚合文档中提取的价格的平均值。
对所有文档进行avg聚合(DSL)
"aggregations" : {
"<aggregation_name>" : { <!--聚合的名字 -->
"<aggregation_type>" : { <!--聚合的类型 -->
<aggregation_body> <!--聚合体:对哪些字
段进行聚合 -->
}
[,"meta" : { [<meta_data_body>] } ]? <!--元 -->
[,"aggregations" : { [<sub_aggregation>]+ } ]? <!--在聚合里面在定义子聚合
-->
}
[,"<aggregation_name_2>" : { ... } ]* <!--聚合的名字 -->
}
+微信study322
专业一手超清完整
全网课程 超低价格以上汇总计算了所有文档的平均值。
"size": 0, 表
示只查询文档聚合数量,不查文档,如查询50,size=50
aggs:表示是一个聚合
czbk:可自定义,聚合后的数据将显示在自定义字段中
OpenAPI查询参数设计
对筛选后的文档聚合
POST product_list_info/_search
{
"size": 0,
"aggs": {
"czbk": {
"avg": {
"field": "price"
}
}
}
}
{
"indexName": "product_list_info",
"map": {
"size": 0,
"aggs": {
"czbk": {
"avg": {
"field": "price"
}
}
}
}
}
POST product_list_info/_search
{
"size": 0,
"query": {
"term": {
"onelevel": "手机通讯"
}
},
+微信study322
专业一手超清完整
全网课程 超低价格"aggs": {
"czbk": {
"avg": {
"field": "price"
}
}
}
}
+微信study322
专业一手超清完整
全网课程 超低价格
OpenAPI查询参数设计
{
"indexName": "product_list_info",
"map": {
"size": 0,
"query": {
"term": {
"onelevel": "手机通讯"
}
},
"aggs": {
"czbk": {
"avg": {
"field": "price"
}
}
}
}
}
根据Script计算平均值:
es所使用的脚本语言是painless这是一门安全-高效的脚本语言,基于jvm的
#统计所有
POST product_list_info/_search?size=0
{
"aggs": {
"czbk": {
"avg": {
"script": {
"source": "doc.evalcount.value"OpenAPI查询参数设计
总结:
avg平均
1、统一avg(所有文档)
2、有条件avg(部分文档)
}
}
}
}
}
结果:"value" : 599929.2282791147
"source": "doc['evalcount']"
"source": "doc.evalcount"
#有条件
POST prod
uct_list_info/_search?size=0
{
"query
"
:
{
"ter
m
"
:
{
"onelevel": "
手机通讯"
}
},
"aggs": {
"czbk": {
"avg": {
"script": {
"source": "doc.evalcount"
}
}
}
}
}
结果:"value" : 600055.6935087288
{
"indexName": "product_list_info",
"map": {
"size": 0,
"aggs": {
"czbk": {
"avg": {
"script": {
"source": "doc.evalcount"
}
}
}
}
}
}
+微信study322
专业一手超清完整
全网课程 超低价格3、脚本统计(所有)
4、脚本统计(部分)
代码编写
访问验证
2、Max(最大值)
计算从聚合文档中提取的数值的最大值。
统计所有文档
结果: "value" : 9.9999999E7
OpenAPI查询参数设计
统计过滤后的文档
if (m.getValue() instanceof ParsedAvg) {
m
ap.put("value", ((ParsedAvg) m.getValue()).getValue());
}
http://1
72.17.0.225:6666/v1/analysis/metric/agg
OR
http://localhost:5555/v1/analysis/metric/agg
POST product_list_info/_search
{
"size": 0,
"aggs": {
"czbk": {
"max": {
"field": "price"
}
}
}
}
{
"indexName": "product_list_info",
"map": {
"size": 0,
"aggs": {
"czbk": {
"max": {
"field": "price"
}
}
}
}
}
+微信study322
专业一手超清完整
全网课程 超低价格结果: "value" : 2474000.0
OpenAPI查询参数设计
结果: "value" : 2474000.0
代码编写
访问验证
POST product_list_info/_search
{
"size": 0,
"query": {
"term": {
"onelevel": "手机通讯"
}
},
"aggs": {
"czbk": {
"max": {
"f
ield": "price"
}
}
}
}
{
"indexName": "product_list_info",
"map": {
"size": 0,
"query": {
"term": {
"onelevel": "手机通讯"
}
},
"aggs": {
"czbk": {
"max": {
"field": "price"
}
}
}
}
}
//最大值
if (m.getValue() instanceof ParsedMax) {
map.put("value", ((ParsedMax) m.getValue()).getValue());
}
http://172.17.0.225:6666/v1/analysis/metric/agg
OR
http://localhost:5555/v1/analysis/metric/agg
+微信study322
专业一手超清完整
全网课程 超低价格3、Min(最小值)
计算从聚合文档中提取的数值的最小值。
统计所有文档
结果:"value": 0.0
OpenAPI查询参数设计
统计筛选后的文档
POST product_list_info/_search
{
"size": 0,
"aggs": {
"czbk": {
"min": {
"f
ield": "price"
}
}
}
}
{
"indexName": "product_list_info",
"map": {
"size": 0,
"aggs": {
"czbk": {
"min": {
"field": "price"
}
}
}
}
}
POST product_list_info/_search
{
"size": 1,
"query": {
"term": {
"onelevel": "手机通讯"
}
},
"aggs": {
"czbk": {
"min": {
"field": "price"
}
}
}
}
+微信study322
专业一手超清完整
全网课程 超低价格结果:"value": 0.0
参数size=1;可查询出金额为0的数据
OpenAPI查询参数设计
代码编写
访问验证
4、Sum(总和)
统计所有文档汇总
{
"indexName": "product_list_info",
"map": {
"size
"
:
1
,
"quer
y
"
:
{
"
t
e
rm
"
:
{
"o
n
el
evel": "手机通讯"
}
}
,
"a
ggs": {
"czbk": {
"min": {
"field": "price"
}
}
}
}
}
//最小值
if (m.getValue() instanceof ParsedMin) {
map.put("value", ((ParsedMin) m.getValue()).getValue());
}
http://172.17.0.225:6666/v1/analysis/metric/agg
OR
http://localhost:5555/v1/analysis/metric/agg
POST product_list_info/_search
{
"size": 0,
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
+微信study322
专业一手超清完整
全网课程 超低价格结果:"valu
e" : 3.433611809E7
OpenAPI查询参数设计
代码编写
访问验证
}
}
},
"aggs": {
"czbk": {
"sum": {
"field": "price"
}
}
}
}
{
"indexName": "product_list_info",
"map": {
"size": 0,
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
}
}
},
"aggs": {
"czbk": {
"sum": {
"field": "price"
}
}
}
}
}
//汇总
if (m.getValue() instanceof ParsedSum) {
map.put("value", ((ParsedSum) m.getValue()).getValue());
}
http://172.17.0.225:6666/v1/analysis/metric/agg
OR
http://localhost:5555/v1/analysis/metric/agg
+微信study322
专业一手超清完整
全网课程 超低价格5、 Cardinality(唯一值)
Cardinality Aggre
g
at
ion
m
u
lti-v
a
lu
e
基于
(可
定的字段,
也可以通过脚本计算
)
(
)
,相
s
q
l中的
di
st
in
ct。
cardinality 求
唯一值,即不重复的字段有多少(相当于mysql中的distinct)
统计所有文档
结果:"value" : 103169
OpenAPI查询参数设计
统计筛选后的文档
POST product_list_info/_search
{
"size": 0,
"aggs": {
"czbk": {
"cardinality": {
"field": "storename"
}
}
}
}
{
"indexName": "product_list_info",
"map": {
"size": 0,
"aggs": {
"czbk": {
"cardinality": {
"field": "storename"
}
}
}
}
}
POST product_list_info/_search
{
"size": 0,
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
+微信study322
专业一手超清完整
全网课程 超低价格OpenAPI查询参数设计
代码编写
访问验证
}
}
},
"aggs": {
"czbk": {
"cardinality": {
"field": "storename"
}
}
}
}
{
"indexName": "product_list_info",
"map": {
"size": 0,
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
}
}
},
"aggs": {
"czbk": {
"cardinality": {
"field": "storename"
}
}
}
}
}
if (m.getValue() instanceof ParsedCardinality) {
map.put("value", ((ParsedCardinality) m.getValue()).getValue());
}
http://172.17.0.225:6666/v1/analysis/metric/agg
OR
http://localhost:5555/v1/analysis/metric/agg
+微信study322
专业一手超清完整
全网课程 超低价格3.2.3 多值分析API设计
1、Stats Aggregation
Stats Aggregation,统计聚合。它属于multi-value,基于文档的某个值(可以是特定的数值型字段,
也可以通过脚本计算而来),计算出一些统计信息(min、max、sum、count、avg5个值)
统计所有文档
OpenAPI查询参数设计
统计筛选文档
POST prod
uct_list_info/_search
{
"size"
:
0
,
"aggs"
:
{
"czbk": {
"stats": {
"field": "price"
}
}
}
}
返回
"aggregations" : {
"czbk" : {
"count" : 5072447,
"min" : 0.0,
"max" : 9.9999999E7,
"avg" : 920.1537270512633,
"sum" : 4.66743101232E9
{
"indexName": "product_list_info",
"map": {
"size": 0,
"aggs": {
"czbk": {
"stats": {
"field": "price"
}
}
}
}
}
POST product_list_info/_search
{
"size": 0,
+微信study322
专业一手超清完整
全网课程 超低价格OpenAPI查询参数设计
代码编写
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
}
}
},
"aggs": {
"czbk": {
"sta
t
s
"
:
{
"f
ie
l
d
"
: "price"
}
}
}
}
{
"indexName": "product_list_info",
"map": {
"size": 0,
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
}
}
},
"aggs": {
"czbk": {
"stats": {
"field": "price"
}
}
}
}
}
if (m.getValue() instanceof ParsedStats) {
map.put("count", ((ParsedStats) m.getValue()).getCount());
map.put("min", ((ParsedStats) m.getValue()).getMin());
map.put("max", ((ParsedStats) m.getValue()).getMax());
map.put("avg", ((ParsedStats) m.getValue()).getAvg());
map.put("sum", ((ParsedStats) m.getValue()).getSum());
}
+微信study322
专业一手超清完整
全网课程 超低价格访问验证
2、扩展状态统计
Extended Stats A
ggregation,扩展统计聚合。它属于multi-value,比stats多4个统计结果: 平方
和、方差、标
准差、平均值加/减两个标准差的区间
统计所有文档
返回
sum_of_squares:平方和
variance:方差
std_deviation:标准差
std_deviation_bounds:标准差的区间
OpenAPI查询参数设计
http://172.17.0.225:6666/v1/analysis/metric/agg
OR
http://localhost:5555/v1/analysis/metric/agg
POST product_list_info/_search
{
"size": 0,
"aggs": {
"czbk": {
"extended_stats": {
"field": "price"
}
}
}
}
aggregations" : {
"czbk" : {
"count" : 5072447,
"min" : 0.0,
"max" : 9.9999999E7,
"avg" : 920.1537270512633,
"sum" : 4.66743101232E9,
"sum_of_squares" : 2.0182209054045464E16,
"variance" : 3.9779448262354884E9,
"std_deviation" : 63070.950731977144,
"std_deviation_bounds" : {
"upper" : 127062.05519100555,
"lower" : -125221.74773690302
}
+微信study322
专业一手超清完整
全网课程 超低价格统计筛选后的
文档
sum_of_squares:平方和
variance:方差
std_deviation:标准差
{
"indexName": "product_list_info",
"map": {
"size": 0,
"aggs": {
"czbk": {
"extended_stats": {
"field": "price"
}
}
}
}
}
POST product_list_info/_search
{
"size": 1,
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
}
}
},
"aggs": {
"czbk": {
"extended_stats": {
"field": "price"
}
}
}
}
aggregations" : {
"czbk" : {
"count" : 12402,
"min" : 0.0,
"max" : 2474000.0,
"avg" : 2768.595233833253,
"sum" : 3.433611809E7,
"sum_of_squares" : 6.445447222627729E12,
"variance" : 5.120451870452684E8,
"std_deviation" : 22628.41547800615,
"std_deviation_bounds" : {
"upper" : 48025.42618984555,
"lower" : -42488.23572217905
+微信study322
专业一手超清完整
全网课程 超低价格std_deviation_bounds:标准差的区间
OpenAPI查询参数设计
代码编写
状态统计ParsedStats是扩展状态统计ParsedExtendedStats父类
判断无需更改顺序
访问验证
{
"indexName": "product_list_info",
"map": {
"size": 1,
"quer
y
"
:
{
"
c
o
n
s
t
a
nt
_
s
c
o
re
": {
"
f
il
t
e
r
"
:
{
"
m
a
tc
h
"
:
{
"t
h
r
ee
level": "手机"
}
}
}
},
"aggs": {
"czbk": {
"extended_stats": {
"field": "price"
}
}
}
}
}
//扩展状态统计
else if (m.getValue() instanceof ParsedExtendedStats) {
map.put("count", ((ParsedStats) m.getValue()).getCount());
map.put("min", ((ParsedStats) m.getValue()).getMin());
map.put("max", ((ParsedStats) m.getValue()).getMax());
map.put("avg", ((ParsedStats) m.getValue()).getAvg());
map.put("sum", ((ParsedStats) m.getValue()).getSum());
map.put("sum_of_squares", ((ParsedExtendedStats)
m.getValue()).getSumOfSquares());
map.put("variance", ((ParsedExtendedStats)
m.getValue()).getVariance());
map.put("std_deviation", ((ParsedExtendedStats)
m.getValue()).getStdDeviation());
map.put("lower", ((ParsedExtendedStats)
m.getValue()).getStdDeviationBound(ExtendedStats.Bounds.LOWER));
map.put("upper", ((ParsedExtendedStats)
m.getValue()).getStdDeviationBound(ExtendedStats.Bounds.UPPER));
}
+微信study322
专业一手超清完整
全网课程 超低价格3、百分位度量/百分比统计
Percentiles Aggre
g
at
ion
m
u
lti
-va
lu
e
字段
(
)
计每个值对应的文档
(
)
占比
[
1, 5, 25, 50, 75, 95, 99 ]分位上的值。
它们表示了人们
感兴趣的常用百分位数值。
统计所有文档
返回
OpenAPI查询参数设计
http://172.17.0.225:6666/v1/analysis/metric/agg
OR
http://localhost:5555/v1/analysis/metric/agg
POST product_list_info/_search
{
"size": 0,
"aggs": {
"czbk": {
"percentiles": {
"field": "price"
}
}
}
}
aggregations" : {
"czbk" : {
"values" : {
"1.0" : 0.0,
"5.0" : 15.021825109603165,
"25.0" : 58.669333121791,
"50.0" : 139.7398105623917,
"75.0" : 388.2363222057536,
"95.0" : 3630.78148822216,
"99.0" : 12561.562823894474
}
}
+微信study322
专业一手超清完整
全网课程 超低价格统计筛选后的文档
OpenAPI查询参数设计
{
"indexName": "product_list_info",
"map": {
"size": 0,
"aggs": {
"czbk": {
"percentiles": {
"field": "price"
}
}
}
}
}
POST product_list_info/_search
{
"size": 0,
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
}
}
},
"aggs": {
"czbk": {
"percentiles": {
"field": "price"
}
}
}
}
{
"indexName": "product_list_info",
"map": {
"size": 0,
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
}
}
},
"aggs": {
"czbk": {
+微信study322
专业一手超清完整
全网课程 超低价格代码编写
访问验证
4、百分位等级/百分比排名聚合
百分比排名聚合:这里有另外一个紧密相关的度量叫 percentile_ranks 。 percentiles 度量告诉
我们落在某个百分比以下的所有文档的最小值。
统计所有文档
统计价格在15元之内统计价格在30元之内文档数据占有的百分比
tips:
统计数据会变化
这里的15和30;完全可以理解万SLA的200;比较字段不一样而已
"percentiles": {
"field": "price"
}
}
}
}
}
if (m.g
e
tV
al
ue
(
)
i
n
s
ta
nc
e
o
f
P
a
r
se
d
TD
ig
e
st
Pe
r
c
en
t
i
le
s
)
{
fo
r
(I
t
e
ra
t
o
r<
P
e
r
c
en
t
i
l
e>
it
e
ra
to
r
=
(
(
Pa
r
se
dT
DigestPercentiles)
m.getValue()).iterator(); iterator.hasNext(); ) {
P
e
rc
e
nt
i
l
e
p
=
(
Pe
r
ce
nt
i
le
)
it
e
ra
t
o
r
.n
ext();
m
a
p
.
pu
t
(
p
.
ge
tV
al
u
e
()
,
p
.g
et
Pe
r
ce
n
t
()
)
;
}
}
http://172.17.0.225:6666/v1/analysis/metric/agg
OR
http://localhost:5555/v1/analysis/metric/agg
POST product_list_info/_search
{
"size": 0,
"aggs": {
"czbk": {
"percentile_ranks": {
"field": "price",
"values": [
15,
30
]
}
}
}
}
+微信study322
专业一手超清完整
全网课程 超低价格返回
价格在15元之内的文档数据占比是4.92%
价格在30元之内的文档数据占比是12.72%
OpenAPI查询参数设计
统计过滤后的文档
aggregations" : {
"czbk" : {
"values
"
:
{
"15.0
"
:
4
.92128378837021,
"
30.0" : 12.724827959646579
}
}
}
{
"indexName": "product_list_info",
"map": {
"size": 0,
"aggs": {
"czbk": {
"percentile_ranks": {
"field": "price",
"values": [
15,
30
]
}
}
}
}
}
POST product_list_info/_search
{
"size": 0,
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
}
}
},
"aggs": {
"czbk": {
"percentile_ranks": {
"field": "price",
+微信study322
专业一手超清完整
全网课程 超低价格OpenAPI查询参数
设计
代码编写
访问验证
"values": [
15,
30
]
}
}
}
}
{
"indexName": "product_list_info",
"map
"
:
{
"s
iz
e": 0,
"query": {
"constant_score": {
"filter": {
"match": {
"threelevel": "手机"
}
}
}
},
"aggs": {
"czbk": {
"percentile_ranks": {
"field": "price",
"values": [
15,
30
]
}
}
}
}
}
//百分位等级
else if (m.getValue() instanceof ParsedTDigestPercentileRanks) {
for (Iterator<Percentile> iterator = ((ParsedTDigestPercentileRanks)
m.getValue()).iterator(); iterator.hasNext(); ) {
Percentile p = (Percentile) iterator.next();
map.put(p.getValue(), p.getPercent());
}
}
+微信study322
专业一手超清完整
全网课程 超低价格4 电商平台日志埋点与搜索热词
4.1 什么是
热度搜索
以下为【京东
】热搜词
4.2 提取热度搜索
热搜词分析流程图
http://172.17.0.225:6666/v1/analysis/metric/agg
OR
http://localhost:5555/v1/analysis/metric/agg
+微信study322
专业一手超清完整
全网课程 超低价格4.3 日志埋点
下面的配置针对需要埋点的服务
这里以itheima-service-elasticsearch为例
1、Spring Cloud 整合Log4j2
排除logback的默认集成。
因为Spring Cloud 默认集成了logback, 所以首先要排除logback的集成,在pom.xml文件
2、引入log4j2起步依赖
相比与其他的日志系统,log4j2丢数据这种情况少;disruptor技术,在多线程环境下,性能高于logback
等10倍以上;利用jdk1.5并发的特性,减少了死锁的发生;
<!--排除logback的默认集成 Spring Cloud 默认集成了logback-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
+微信study322
专业一手超清完整
全网课程 超低价格3、设置配置文件
如果自定义了
文件名,需要在application.yml中配置
进入Nacos修改配置
4、配置文件模板
从配置文件中可以看到,这里使用的是Socket Appender来将日志打印的信息发送到Logstash。
注意了,Socket的Appender必须要配置到下面的Logger才能将日志输出到Logstash里!
另外这里的host是部署了Logstash服务端的地址,并且端口号要和你在Logstash里配置的一致才行。
5、日志埋点
<!-- 引入log4j2起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- log4j2依赖环形队列-->
<dependency>
<groupId>com.lmax</groupId>
<
a
rt
i
f
ac
tI
d
>
d
i
s
r
u
pt
o
r<
/
artifactId>
<
v
e
r
s
io
n>
3
.
4
.2
<
/
v
e
r
si
o
n>
</dependency>
logging:
config: classpath:log4j2-dev.xml
<Configuration>
<Appenders>
<Socket name="Socket" host="172.17.0.225" port="4567">
<JsonLayout compact="true" eventEol="true" />
</Socket>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Socket"/>
</Root>
</Loggers>
</Configuration>
+微信study322
专业一手超清完整
全网课程 超低价格6.创建索引
下面的索引存储用户输入的关键字,最终通过聚合的方式处理索引数据,最终将数据放到语料库
4.4 数据落盘
1、配置Logstash.conf
连接logstash方式有两种
(1) 一种是Socket连接
(2)另外一种是gelf连接
private void getClientConditions(CommonEntity commonEntity,
SearchSourceBuilder searchSourceBuilder) {
//循环前端的查询条件
for (Map.Entry<String, Object> m : commonEntity.getMap().entrySet()) {
if (StringUtils.isNotEmpty(m.getKey()) && m.getValue() != null) {
String key = m.getKey();
String value = String.valueOf(m.getValue());
//构造请求体中“query”:{}部分的内容 ,QueryBuilders静态工厂类,方便构造
queryBuilder
searchSourceBuilder.query(QueryBuilders.matchQuery(key, value));
logger.info("search for the keyword:" + value);
}
}
}
PUT es-log/
{
"mappings": {
"properties": {
"@timestamp": {
"type": "date"
},
"host": {
"type": "text"
},
"searchkey": {
"type": "keyword"
},
"port": {
"type": "long"
},
"loggerName": {
"type": "text"
}
}
}
}
input {
+微信study322
专业一手超清完整
全网课程 超低价格重启Logstash,对外暴露4567端口
2、执行全文检索
tcp {
port => 4567
codec => json
}
}
filter {
#如果不包含search for the keyword则删除
if [message] =~ "^(?!.*?search for the keyword).*$" {
drop
{}
}
mutat
e
{
#移除不需要
re
m
o
v
e
_
fi
e
l
d
=
>
["thread
P
r
i
o
r
i
ty
"
,
"
e
n
dO
fBatch","level","@version","threadId","tags","loggerFqcn"
,"thread","instant"]
#对原始数据按照:分组,取分组后的搜索关键字
split=>["message",":"]
add_field => {
"searchkey" => "%{[message][1]}"
}
#上面新增了searchkey新列,移除老的message列
remove_field => ["message"]
}
}
# 输出部分
output {
elasticsearch {
# elasticsearch索引名
index => "es-log"
# elasticsearch的ip和端口号
hosts => ["172.188.0.88:9200","172.188.0.89:9201","172.188.0.90:9202"]
}
stdout {
codec => json_lines
}
}
docker run --name logstash -p 4567:4567 -v
/usr/local/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
-v /usr/local/logstash/config/conf.d/:/usr/share/logstash/pipeline/ -v
/usr/local/logstash/config/jars/mysql-connector-java-
5.1.48.jar:/usr/share/logstash/logstash-core/lib/jars/mysql-connector-java-
5.1.48.jar --net czbkNetwork --ip 172.188.0.77 --privileged=true -d
c2c1ac6b995b
+微信study322
专业一手超清完整
全网课程 超低价格参数
3、查询是否有数据
返回
4.5 热度搜索OpenAPI
1、聚合
获取es-log索引中的文档数据并对其进行分组,统计热搜词出现的频率,根据频率获取有效数据。
http://localhost:8888/v1/docs/mquery
{
"pageNumber": 1,
"pageSize": 3,
"indexNam
e"
:
"
p
r
o
d
u
c
t
_
l
i
st
_
info",
"highligh
t
"
:
"
p
r
o
d
u
c
t
na
m
e
"
,
"map": {
"
productname": "小米"
}
}
GET es-log/_search
{
"from": 0,
"size": 200,
"query": {
"match_all": {}
}}
{
"_index" : "es-log",
"_type" : "_doc",
"_id" : "s4sdPHEBfG2xXcKw2Qsg",
"_score" : 1.0,
"_source" : {
"searchkey" : "华为全面屏",
"port" : 51140,
"@timestamp" : "2020-04-02T18:18:41.085Z",
"host" : "192.168.23.1",
"loggerName" :
"com.itheima.service.impl.ElasticsearchDocumentServiceImpl"
}
}
+微信study322
专业一手超清完整
全网课程 超低价格2、DSL实现
fifield:查询的列,keyword类型
min_doc_count:热度大于1次的
order:热度排序
size:取出前几个
per_count:"自定义聚合名
结果
POST es-log/_search?size=0
{
"aggs": {
"czbk": {
"terms": {
"fiel
d
"
:
"
se
a
rc
h
ke
y
",
"min_
do
c
_c
o
u
nt
"
:
5
,
"size": 2,
"o
r
de
r
"
:
{
"
_
co
u
n
t
": "desc"
}
}
}
}
}
{
"took" : 13,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 40,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"per_count" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 12,
"buckets" : [
{
"key" : "阿迪达斯外套",
"doc_count" : 14
},
{
+微信study322
专业一手超清完整
全网课程 超低价格4、 OpenAP
I查询参数设计
1、定义搜索推荐接口
2、定义搜索推荐实现
"key" : "华为",
"doc_count" : 8
}
]
}
}
}
package com.itheima.service;
import com.itheima.commons.pojo.CommonEntity;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.ParsedAggregation;
import org.elasticsearch.search.aggregations.metrics.ParsedStats;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import java.util.List;
import java.util.Map;
/**
* @Class: AnalysisService
* @Package com.itheima.service
* @Description: 分析接口
* @Company: http://www.itheima.com/
*/
public interface AnalysisService {
//获取搜索热词
public Map<String, Long> hotwords(CommonEntity commonEntity) throws
Exception;
}
/*
* @Description: 获取搜索热词
* @Method: hotwords
* @Param: [commonEntity]
* @Update:
* @since: 1.0.0
* @Return: java.util.List<java.lang.String>
*
*/
+微信study322
专业一手超清完整
全网课程 超低价格3、定义搜索推荐控制器
public Map<String, Long> hotwords(CommonEntity commonEntity) throws
Exception {
//定义返回数据
Map<String, Long> map = new HashMap<String, Long>();
//执行查询
SearchResponse result = getSearchResponse(commonEntity);
//这里的自定义的分组别名(get里面)key当一个的时候为动态获取
Terms packageAgg =
result.getAggregations().get(result.getAggregations().getAsMap().entrySet().iter
ator().next()
.g
e
tK
e
y
()
)
;
for (
T
e
rm
s
.
Bu
c
ke
t entry : packageAgg.getBuckets()) {
i
f
(
e
n
t
ry
.
ge
tK
ey
(
)
!= null) {
/
/
k
ey
S
t
r
i
ng
k
ey
=
e
n
tr
y.getKey().toString();
/
/
c
o
u
nt
Long count = entry.getDocCount();
map.put(key, count);
}
}
return map;
}
/*
* @Description: 搜索热词
* @Method: tSuggest
* @Param: [commonEntity]
* @Update:
* @since: 1.0.0
* @Return: com.itheima.commons.result.ResponseData
*
*/
@GetMapping(value = "/hotwords")
public ResponseData hotwords(@RequestBody CommonEntity commonEntity) {
// 构造返回数据
ResponseData rData = new ResponseData();
if (StringUtils.isEmpty(commonEntity.getIndexName())) {
rData.setResultEnum(ResultEnum.param_isnull);
return rData;
}
//批量查询返回结果
Map<String, Long> result = null;
try {
//通过高阶API调用批量新增操作方法
result = analysisService.hotwords(commonEntity);
//通过类型推断自动装箱(多个参数取交集)
rData.setResultEnum(result, ResultEnum.success, null);
//日志记录
logger.info(TipsEnum.hotwords_get_doc_success.getMessage());
} catch (Exception e) {
//打印到控制台
e.printStackTrace();
//日志记录
logger.error(TipsEnum.hotwords_get_doc_fail.getMessage());
+微信study322
专业一手超清完整
全网课程 超低价格4、调用验证
获取分析服务热搜词
数据
参数
fifield表示需要查找的列
min_doc_count:热搜词在文档中出现的次数
size表示本次取出多少数据
order表示排序(升序or降序)
返回
4.6 微服务容器化部署
1、itheima-service-gateway
//构建错误返回信息
rData.setResultEnum(ResultEnum.error);
}
return rData;
}
http://loc
alhost:5555/v1/analysis/hotwords
{
"indexName": "es-log",
"map": {
"aggs": {
"per_count": {
"terms": {
"field": "searchkey",
"min_doc_count": 5,
"size": 2,
"order": {
"_count": "desc"
}
}
}
}
}
}
{
"code": "200",
"desc": "操作成功!",
"data": {
"华为": 8,
"阿迪达斯外套": 14
}
}
+微信study322
专业一手超清完整
全网课程 超低价格设置POM和Dockfifile文件
设置网关路由
发布到Dokcer
启动
访问
2、itheima-service-elasticsearch
设置POM和Dockfifile文件
设置日志配置(日志yml和日志xml)
发布到Docker
启动
3、itheima-service-analysis
设置POM和Dockfifile文件
发布到Docker
启动
docker run --name service-gateway --net czbkNetwork --ip 172.188.0.22 --
privileged=true -p 6666:6666 --restart=always -d itheima-service
gateway:1
.0.0.RELEASE
http
://172.17.0.225:6666/v1/docs/mquery
{
"pageNumber": 0,
"pageSize": 1,
"indexName": "product_list_info",
"highlight": "productname",
"map": {
"productname": "华为全面屏"
}
}
docker run --name service-elasticsearch --net czbkNetwork --ip
172.188.0.33 --privileged=true --restart=always -p 8888:8888 -d
itheima-service-elasticsearch:1.0.0.RELEASE
docker run --name service-analysis --net czbkNetwork --ip 172.188.0.34 --
privileged=true -p 5555:5555 --restart=always -d itheima-service
analysis:1.0.0.RELEASE
+微信study322
专业一手超清完整
全网课程 超低价格+微信study322
专业一手超清完整
全网课程 超低价格
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值