1 准备数据
- 构建个文章的索引
PUT article
{
"mappings": {
"properties": {
"id":{
"type": "long"
},
"title":{
"type": "text",
"analyzer": "ik_max_word"
},
"category":{
"type": "keyword"
},
"author":{
"type": "text",
"analyzer": "ik_max_word"
},
"content":{
"type": "text",
"analyzer": "ik_max_word"
},
"createAt":{
"type": "date",
"format": ["yyyy-MM-dd hh:mm:ss"]
}
}
}
}
- 先插入一条数据,后面根据测试的需要进行增加
PUT article/_doc/1
{
"id":1,
"title":"elasticsearch技术解析与实战",
"category":"计算机技术",
"author":"朱林",
"content":"elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
"createAt":"2016-12-12 10:00:00"
}
- 根据id查询一下数据
请求
GET article/_doc/1
响应
{
"_index" : "article",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"id" : 1,
"title" : "elasticsearch技术解析与实战",
"category" : "计算机技术",
"author" : "朱林",
"content" : "elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
"createAt" : "2016-12-12 10:00:00"
}
}
2 url搜索
请求格式:
GET http"//localhost:9200/索引库名字/_search?参数
,多个参数使用&
符号分开。
参数一:q:查询字符串
可以指定查询字段,如果不指定,es 会查询所有字段
例如:
# 查询id为1的文档
GET article/_search?q=id:1
# 查询author为朱林的
GET article/_search?q=author:朱林
# 查询author包含朱
GET article/_search?q=author:朱
# 查询类目为计算机技术
GET article/_search?q=category:计算机技术
GET article/_search?q=category:计算机
除了最后一个查不出刚刚数据:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
很简单的类目字段为keyword,不会被分词,所以类目查询计算机
是会被搜索出来的,而作者字段类型是text,会被分词,所以查询朱还是林又或者是朱林都能被索引出来。
之前讲过的source过滤,超市时间也是可以的
# 只返回title和author字段,超时时间为5m
GET article/_search?q=category:计算机技术&_source_includes=title,author&timeout=5m
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "article",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"author" : "朱林",
"title" : "elasticsearch技术解析与实战"
}
}
]
}
}
当然也可以不指定字段,这就是查询所有字段
GET article/_search?q=朱林
新增一条数据
PUT article/_doc/2
{
"id":2,
"title":"朱林传记",
"category":"传记",
"author":"王小虎",
"content":"资深开发人员,有16年开发经验,11年安全产品开发经验,对安全技术、日志分析有较深的研究。于2013年创立南京赛克蓝德网络科技有限公司,公司专注于安全产品的开发,目前主要开发的产品是赛克蓝德日志分析软件。",
"createAt":"2016-12-12 10:00:00"
}
执行上面的查询,就会把两条数据都搜索出来
{
"took" : 632,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.5442266,
"hits" : [
{
"_index" : "article",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.5442266,
"_source" : {
"id" : 2,
"title" : "朱林传记",
"category" : "传记",
"author" : "王小虎",
"content" : "资深开发人员,有16年开发经验,11年安全产品开发经验,对安全技术、日志分析有较深的研究。于2013年创立南京赛克蓝德网络科技有限公司,公司专注于安全产品的开发,目前主要开发的产品是赛克蓝德日志分析软件。",
"createAt" : "2016-12-12 10:00:00"
}
},
{
"_index" : "article",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.3862942,
"_source" : {
"id" : 1,
"title" : "elasticsearch技术解析与实战",
"category" : "计算机技术",
"author" : "朱林",
"content" : "elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
"createAt" : "2016-12-12 10:00:00"
}
}
]
}
}
执行下面的查询就只会查出一条数据:author是朱林的那条
GET article/_search?q=author:朱林
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.3862942,
"hits" : [
{
"_index" : "article",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.3862942,
"_source" : {
"id" : 1,
"title" : "elasticsearch技术解析与实战",
"category" : "计算机技术",
"author" : "朱林",
"content" : "elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
"createAt" : "2016-12-12 10:00:00"
}
}
]
}
}
参数2:df
定义查询时,默认的查询字段
GET article/_search?q=朱林&df=author
这里就指定了默认查询字段是author,刚刚上面没有指定,会查询出两条数据,这里指定了就只会去查询author字段,只会查询:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.3862942,
"hits" : [
{
"_index" : "article",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.3862942,
"_source" : {
"id" : 1,
"title" : "elasticsearch技术解析与实战",
"category" : "计算机技术",
"author" : "朱林",
"content" : "elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
"createAt" : "2016-12-12 10:00:00"
}
}
]
}
}
参数3 timeout
搜索超时,将搜索请求限制在指定的时间值内执行,并使用在到期时累积的点击数进行保释。默认为无超时。
参数 sort
排序执行。可以是fieldName或 fieldName:asc / fieldName:desc。fieldName可以是文档中的实际字段,也可以是特殊_score名称,表示基于分数的排序。可以有几个sort参数(顺序很重要)。
# 根据id降序
GET article/_search?sort=id:desc
# 也可以是_score这种特殊字段
GET article/_search?sort=_score:desc
设置了排序字段就不会返回评分信息了(除了按照_score排序之外)
参数 track_scores
通过这个参数就可以,在使用其他排序字段的时候,依旧返回得分情况,默认是false
GET article/_search?sort=id:desc&track_scores=true
参数 _source
设置为false禁用_source字段检索。您还可以使用_source_include&检索部分文档_source_exclude,默认是true
这个前面已经介绍过:https://blog.csdn.net/wyaoyao93/article/details/110325063
GET article/_search?q=category:计算机技术&_source_includes=title,author
参数 track_total_hits
设置为false禁用跟踪与查询匹配的匹配总数。默认为true。
设置为false,不会返回匹配的总条数,total字段返回值为-1
简单来说就是返回查询到的总数
GET article/_search?track_total_hits=false
参数 search_type
要执行的搜索操作的类型。可以是 dfs_query_then_fetch或query_then_fetch。默认为query_then_fetch。有关可以执行的不同搜索类型的更多详细信息,请参阅 搜索类型。
参数 explain
每个返回结果中,将包含评分机制的解释,默认是false
GET article/_search?explain=true
参数 terminate_after: 每个分片中查询的最大条数
每个分片中查询的最大条数,如果设置了,返回结果中会有一个terminated_early字段
GET article/_search?terminate_after=1
{
"took" : 0,
"timed_out" : false,
"terminated_early" : true,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "article",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"id" : 1,
"title" : "elasticsearch技术解析与实战",
"category" : "计算机技术",
"author" : "朱林",
"content" : "elasticsearch是目前全球最受欢迎的全文搜索引擎技术。本书将首先介绍其相关的基础知识,然后由浅入深的介绍其索引查询相关的知识,接着介绍其集群,分词等重要的配置,最后介绍其相关的其他产品。",
"createAt" : "2016-12-12 10:00:00"
}
}
]
}
}
这里只查出一条,因为我们就一个分片,每个分片最大返回1条,所以只返回了一条数据
分页: from和size
from:索引匹配结果的偏移值,默认是0
size:默认是10,搜索结果返回的条数
# 查询第一页,每页1条
GET article/_search?from=0&size=1
# 查询第二页,每页1条
GET article/_search?from=1&size=1
3 Search Type(搜索类型)
3.1 分布式搜索背景介绍
ES天生就是为分布式而生,但分布式有分布式的缺点。比如要搜索某个单词,但是数据却分别在5个分片(Shard)上面,这5个分片可能在5台主机上面。因为全文搜索天生就要排序(按照匹配度进行排名),但数据却在5个分片上,如何得到最后正确的排序呢?ES是这样做的,大概分两步。
- ES客户端会将这个搜索词同时向5个分片发起搜索请求,这叫Scatter,
- 这5个分片基于本Shard独立完成搜索,然后将符合条件的结果全部返回,这一步叫Gather。
客户端将返回的结果进行重新排序和排名,最后返回给用户。也就是说,ES的一次搜索,是一次scatter/gather过程(这个跟mapreduce也很类似).
3.2 两个问题
数量问题
比如,用户需要搜索”双黄连”,要求返回最符合条件的前10条。但在5个分片中,可能都存储着双黄连相关的数据。所以ES会向这5个分片都发出查询请求,并且要求每个分片都返回符合条件的10条记录。当ES得到返回的结果后,进行整体排序,然后取最符合条件的前10条返给用户。这种情况,ES最多会收到10*5=50条记录
排名问题
上面搜索,每个分片计算分值都是基于自己的分片数据进行计算的。计算分值使用的词频率和其他信息都是基于自己的分片进行的,而ES进行整体排名是基于每个分片计算后的分值进行排序的,这就可能会导致排名不准确的问题。如果我们想更精确的控制排序,应该先将计算排序和排名相关的信息(词频率等)从5个分片收集上来,进行统一计算,然后使用整体的词频率去每个分片进行查询
3.3 Search Type
为了解决上面的问题,es提出了Search Type的概念,交给用户来选择不同的搜索类型
query and fetch
向索引的所有分片(shard)都发出查询请求,各分片返回的时候把元素文档(document)和计算后的排名信息一起返回。这种搜索方式是最快的。因为相比下面的几种搜索方式,这种查询方法只需要去shard查询一次。但是各个shard返回的结果的数量之和可能是用户要求的size的n倍。
query then fetch(默认的搜索方式)
这种搜索方式,大概分两个步骤,第一步,先向所有的shard发出请求,各分片只返回排序和排名相关的信息(注意,不包括文档document),然后按照各分片返回的分数进行重新排序和排名,取前size个文档。然后进行第二步,去相关的shard取document。
DFS query and fetch
这种方式比query and fetch多了一个初始化散发(initial scatter)步骤,有这一步,据说可以更精确控制搜索打分和排名。DFS query and fetch 返回结果的数量是 分片数*size
DFS query then fetch
比query then fetch多了一个初始化散发(initial scatter)步骤。这种方式返回的document与用户要求的size是相等的。
总结一下,从性能考虑QUERY_AND_FETCH是最快的,DFS_QUERY_THEN_FETCH是最慢的。从搜索的准确度来说,DFS要比非DFS的准确度更高