ElasticSearch之搜索引擎结果分析

篇幅有限

完整内容及源码关注公众号:ReverseCode,发送

_search解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
GET /_search

{
"took": 6,
"timed_out": false,
"_shards": {
"total": 6,
"successful": 6,
"failed": 0
},
"hits": {
"total": 10,
"max_score": 1,
"hits": [
{
"_index": ".kibana",
"_type": "config",
"_id": "5.2.0",
"_score": 1,
"_source": {
"buildNum": 14695
}
}
]
}
}

took:整个搜索请求花费了多少毫秒

hits.total:本次搜索,返回了几条结果
hits.max_score:本次搜索的所有结果中,最大的相关度分数是多少,每一条document对于search的相关度,越相关,_score分数越大,排位越靠前
hits.hits:默认查询前10条数据,完整数据,_score降序排序

shards:shards fail的条件(primary和replica全部挂掉),不影响其他shard。默认情况下来说,一个搜索请求,会打到一个index的所有primary shard上去,当然了,每个primary shard都可能会有一个或多个replic shard,所以请求也可以到primary shard的其中一个replica shard上去。

timeout:默认无timeout,latency平衡completeness,手动指定timeout,timeout查询执行机制

timeout=10ms,timeout=1s,timeout=1m
GET /_search?timeout=10m

image-20210526102317567

搜索模式解析

multi-index和multi-type搜索模式

1
2
3
4
5
6
7
8
/_search:所有索引,所有type下的所有数据都搜索出来
/index1/_search:指定一个index,搜索其下所有type的数据
/index1,index2/_search:同时搜索两个index下的数据
/*1,*2/_search:按照通配符去匹配多个索引
/index1/type1/_search:搜索一个index下指定的type的数据
/index1/type1,type2/_search:可以搜索一个index下多个type的数据
/index1,index2/type1,type2/_search:搜索多个index下的多个type的数据
/_all/type1,type2/_search:_all可以代表搜索所有index下的指定type的数据

image-20210526103022096

  1. exact value

2017-01-01,exact value,搜索的时候,必须输入2017-01-01,才能搜索出来,如果你输入一个01,是搜索不出来的

  1. full text
    (1)缩写 vs. 全程:cn vs. china
    (2)格式转化:like liked likes
    (3)大小写:Tom vs tom
    (4)同义词:like vs love

2017-01-01,2017 01 01,搜索2017,或者01,都可以搜索出来
china,搜索cn,也可以将china搜索出来
likes,搜索like,也可以将likes搜索出来
Tom,搜索tom,也可以将Tom搜索出来
like,搜索love,同义词,也可以将like搜索出来

就不是说单纯的只是匹配完整的一个值,而是可以对值进行拆分词语后(分词)进行匹配,也可以通过缩写、时态、大小写、同义词等进行匹配。

倒排索引

doc1:I really liked my small dogs, and I think my mom also liked them.
doc2:He never liked any dogs, so I hope that my mom will not expect me to liked him.

mother like little dog,不可能有任何结果

normalization,建立倒排索引的时候,会执行一个操作,也就是说对拆分出的各个单词进行相应的处理,以提升后面搜索的时候能够搜索到相关联的文档的概率,包括时态的转换,单复数的转换,同义词的转换,大小写的转换。

worddoc1doc2
I**
really*
like**
my**
little*
dog**
and*
think*
mom**
also*
them*
He*
never*
any*
so*
hope*
that*
will*
not*
expect*
me*
to*
him*

分词器

切分词语,normalization(提升recall召回率),将句子拆分成一个一个的单个的单词,同时对每个单词进行normalization(时态转换,单复数转换),分词器。

recall召回率:搜索的时候,增加能够搜索到的结果的数量

1
2
3
character filter:在一段文本进行分词之前,先进行预处理,比如说最常见的就是,过滤html标签(<span>hello<span> --> hello),& --> and(I&you --> I and you)
tokenizer:分词,hello you and me --> hello, you, and, me
token filter:lowercase,stop word,synonymom,dogs --> dog,liked --> like,Tom --> tom,a/the/an --> 干掉,mother --> mom,small --> little

内置分词器

Set the shape to semi-transparent by calling set_trans(5)

1
2
3
4
standard analyzer:set, the, shape, to, semi, transparent, by, calling, set_trans, 5(默认的是standard)
simple analyzer:set, the, shape, to, semi, transparent, by, calling, set, trans
whitespace analyzer:Set, the, shape, to, semi-transparent, by, calling, set_trans(5)
language analyzer(特定的语言的分词器,比如说,english,英语分词器):set, shape, semi, transpar, call, set_tran, 5

分页搜索

es进行分页搜索

size,from

1
2
3
4
5
6
7
GET /_search?size=10
GET /_search?size=10&from=0
GET /_search?size=10&from=20
GET /test_index/test_type/_search 总共有9条
GET /test_index/test_type/_search?from=0&size=3 将这9条数据分成3页,每一页是3条数据
GET /test_index/test_type/_search?from=3&size=3
GET /test_index/test_type/_search?from=6&size=3

deep paging

image-20210526105008431

query string

1
2
3
4
GET /test_index/test_type/_search?q=test_field:test   包含
GET /test_index/test_type/_search?q=+test_field:test 包含
GET /test_index/test_type/_search?q=-test_field:test 不包含
GET /test_index/test_type/_search?q=test 直接可以搜索所有的field,任意一个field包含指定的关键字就可以搜索出来

es中的_all元数据,在建立索引的时候,我们插入一条document,它里面包含了多个field,此时,es会自动将多个field的值,全部用字符串的方式串联起来,变成一个长的字符串,作为_all field的值,同时建立索引,后面如果在搜索的时候,没有对某个field指定搜索,就默认搜索_all field,其中是包含了所有field的值的。

1
2
3
4
5
6
{
"name": "jack",
"age": 26,
"email": "jack@sina.com",
"address": "guamgzhou"
}

jack 26 jack@sina.com guangzhou,作为这一条document的_all field的值,同时进行分词后建立对应的倒排索引

mapping

插入几条数据,让es自动为我们建立一个索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
PUT /website/article/1
{
"post_date": "2017-01-01",
"title": "my first article",
"content": "this is my first article in this website",
"author_id": 11400
}

PUT /website/article/2
{
"post_date": "2017-01-02",
"title": "my second article",
"content": "this is my second article in this website",
"author_id": 11400
}

PUT /website/article/3
{
"post_date": "2017-01-03",
"title": "my third article",
"content": "this is my third article in this website",
"author_id": 11400
}

GET /website/article/_search?q=2017 3条结果
GET /website/article/_search?q=2017-01-01 3条结果
GET /website/article/_search?q=post_date:2017-01-01 1条结果
GET /website/article/_search?q=post_date:2017 1条结果

dynamic mapping,自动为我们建立index,创建type,以及type对应的mapping,mapping中包含了每个field对应的数据类型,以及如何分词等设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
GET /website/_mapping/article

{
"website": {
"mappings": {
"article": {
"properties": {
"author_id": {
"type": "long"
},
"content": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"post_date": {
"type": "date"
},
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}

因为es自动建立mapping的时候,设置了不同的field不同的data type。不同的data type的分词、搜索等行为是不一样的。所以出现了_all field和post_date field的搜索表现完全不一样。

文章作者: J
文章链接: http://onejane.github.io/2021/05/25/ElasticSearch之搜索引擎结果分析/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 万物皆可逆向
支付宝打赏
微信打赏