目录
前言
在我们学习搜索查询之前,我们需要先学习一些前置知识,包含了 上下文,元数据,文档源数据,评分。如果我们对ES的查询结果的结构及内容含义都不知道的话,学习搜索会相当不优化, 正所谓磨刀不误砍柴工,让我们开始吧。
首先我们先往ES中写入一些数据, 为大家贴在下面了。
PUT /product/_doc/1
{
"name" : "xiaomi phone",
"desc" : "shouji zhong de zhandouji",
"price" : 3999,
"lv":"qijianji",
"type":"phone",
"createtime":"2020-10-01T08:00:00Z",
"tags": [ "xingjiabi", "fashao","buka" ]
}
PUT /product/_doc/2
{
"name" : "xiaomi nfc phone",
"desc" : "zhichi quangongneng nfc,shouji zhong de jianjiji",
"price" : 4999,
"lv":"qijianji",
"type":"phone",
"createtime":"2020-05-21T08:00:00Z",
"tags": [ "xingjiabi", "fashao","gongjiaoka" ]
}
PUT /product/_doc/3
{
"name" : "nfc phone",
"desc" : "shouji zhong de hongzhaji ",
"price" : 2999,
"lv":"gaoduanji",
"type":"phone",
"createtime":"2020-06-20",
"tags": [ "xingjiabi", "fashao", "menjinka" ]
}
PUT /product/_doc/4
{
"name" : "xiaomi erji",
"desc" : "erji zhong de huangmenji",
"price" : 999,
"lv":"baiyuanji",
"type":"erji",
"createtime":"2020-06-23",
"tags": [ "low", "bufangshui","yinzhicha" ]
}
PUT /product/_doc/5
{
"name" : "hongmi erji",
"desc" : "erji zhong de kendeji nfc",
"price" : 399,
"type":"erji",
"lv":"baiyuanji",
"createtime":"2020-07-20",
"tags": [ "lowbee","xuhangduan", "zhiliangx" ]
}
PUT /product/_doc/6
{
"name" : "xiaomi phone 10",
"desc" : "chongdian zeikuai diaodian gengkuai,chaoji wudi wangyuanjing,gaoshua dianjingping",
"price" : "5999",
"lv":"qijianji",
"type":"phone",
"createtime":"2020-07-27",
"tags": [ "120Hz", "120W", "120bianjiao" ]
}
PUT /product/_doc/7
{
"name" : "aipao SE2",
"desc" : "chule CPU,nothing",
"price" : "3299",
"lv":"qijianji",
"type":"phone",
"createtime":"2020-07-21",
"tags": [ "gejiucai", "gejiujiucai", "gexinjiucai" ]
}
PUT /product/_doc/8
{
"name" : "XS Max",
"desc" : "tingshuo yaochu 12 le zhongyu keyi huandiao shouli de 4S le",
"price" : 4399,
"lv":"qijianji",
"type":"shouji",
"createtime":"2020-08-19",
"tags": [ "5V1A", "4Gquanwangtong", "big" ]
}
PUT /product/_doc/9
{
"name" : "xiaomi TV",
"desc" : "Sydney's KTV",
"price" : 2998,
"lv":"gaoduanji",
"type":"erji",
"createtime":"2020-08-16",
"tags": [ "jumo", "jiatingyingyuan", "games" ]
}
PUT /product/_doc/10
{
"name" : "hongmi TV",
"desc" : "wo bishangmian nage genghuasuan,woye 2998,woye 70 cun,danshi wo genghaokan",
"price" : 2999,
"type":"TV",
"lv":"gaoduanji",
"createtime":"2020-08-28",
"tags": [ "dapian", "languang8K", "chaobo" ]
}
一. 上下文
首先我们查询一个索引(文末附有本篇文章的数据, 各位可以先将数据写入自己的ES中)
如下图, 这里对查询的结果进行一个解析:
- took: 表示这次请求消耗了多少时间
- time_out:本次请求是否超时
- _shards: 当前请求的分片信息
- total: 分片总数量
- successful: 分片请求成功数量
- skipped:跳过分片数量
- failed:分片请求失败数量
- hits:当前请求查询到的结果
- total: 结果相关信息
- value:结果总数量
- relation:当前查询关系
- max_score:当前查询结果中的最大评分值
- hits:当前返回的结果集合,里面包含了若干个文档。
GET /product/_search
以上就是ES中查询结果的上下文, 简而言之就是 真正查询到结果(第二层级的hits)以上位置的数据被称之为上下文。
二. 元数据
讲解完上下文后,我们往下看,接下来就到了我们查询到的文档数据。
上图为ES中的一条文档数据, 可以理解为mysql中的一行数据, 只不是ES是以机构化json的方式进行存储, 我们对结果进行一个解析:
- _index:本次查询请求的索引名称
- _id:文档的id
- _score:文档的评分值
- _source:文档的源数据,就是我们实际上业务使用的数据。
三. 评分
1. 概念
评分在ES中是一个非常非常非常重要的概念,大家一定要理解评分的作用及用法。
在ES进行全文检索时,会对根据搜索条件和文档内容进行一个匹配度打分,匹配度越高得到的评分也就越高。而当我们查询时并没有指定排序字段的话, ES是默认根据评分来进行排名。
大家可以试想一下,当我们在百度中搜索一个关键字或者一段话,是不是按照相关内容最多到最少的顺序来展示?这样是不是就很好理解了这个评分的概念。
2. 示例
只说概念的话大家可能不好理解, 这里给大家展示一个简单的案例让大家有更好的学习。
我们通过match查询 desc 字段包含 "shouji zhong de" 的结果.
#查询代码
GET /product/_search
{
"query": {
"match": {
"desc": "shouji zhong de"
}
}
}
这里查询结果比较多, 这里为了方便查看, 只截图了三条结果,我们对比三条数据的_score值,可以发现:
- 结果1和结果2的评分值是一样的
- 结果3的评分值略低
因为我们可以知道ES是根据评分值默认排序的, 那为什么数据1和数据2的评分会一样呢?
大家可以用肉眼观察数据1和数据2的desc字段, 可以发现它们都完全包含了"shouji zhong de"这个短语, 并且这个短语在两条数据中所占字符的比例是相同的, 因此两条数据的评分值是一模一样的