一、知识铺垫
1.1、搜索结果各项含义
GET /_search { "took": 6, #整个搜索请求花费了多少毫秒 "timed_out": false, #是否超时,可以手动指定超时时间 "_shards": { #默认一个搜索请求,会打到index的所有primary shard上去,每个primary shard都可能会有一个或多个replic shard,所以请求也可以到primary shard的其中一个replica shard上去。 "total": 6, "successful": 6, #shards fail的条件(primary和replica全部挂掉) "failed": 0 }, "hits": { "total": 10, #本次搜索,返回了几条结果 "max_score": 1, #本次搜索的所有结果中,最大的相关度分数是多少,每一条document对于search的相关度,越相关,_score分数越大,排位越靠前 "hits": [ #默认查询前10条数据,完整数据,_score降序排序 { "_index": ".kibana", "_type": "config", "_id": "5.2.0", "_score": 1, "_source": { "buildNum": 14695 } } ] } }
对于timeout:可以手动指定超时时间,如timeout=10ms,timeout=1s,timeout=1m ==>GET /_search?timeout=10m
1.2、multi-index和multi-type搜索模式
/_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的数据
1.3、分页搜索
GET /_search?size=10 GET /_search?size=10&from=0 GET /_search?size=10&from=20 GET /test_index/test_type/_search?from=0&size=3
1.4、query string基础语法及_all metadata的原理和作用
1.4.1、query string基础语法
GET /test_index/test_type/_search?q=test_field:test #表示test_field字段包含test的document GET /test_index/test_type/_search?q=+test_field:test #"+"表示test_field字段包含test的document GET /test_index/test_type/_search?q=-test_field:test #"-"表示test_field字段不包含test的document
1.4.2、_all metadata的原理和作用
GET /test_index/test_type/_search?q=test
直接可以搜索所有的field,任意一个field包含指定的关键字就可以搜索出来。
es会自动将多个field的值,全部用字符串的方式串联起来,变成一个长的字符串,作为_all field的值,同时建立索引
后面如果在搜索的时候,没有对某个field指定搜索,就默认搜索_all field
#例如 { "name": "jack", "age": 26, "email": "jack@sina.com", "address": "guamgzhou" } "jack 26 jack@sina.com guangzhou",作为这一条document的_all field的值,同时进行分词后建立对应的倒排索引
二、mapping
2.1、mapping的引入
插入几条数据,让es自动为我们建立一个索引
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条结果
自动或手动为index中的type建立的一种数据结构和相关配置,简称为mapping
dynamic mapping,自动为我们建立index,创建type,以及type对应的mapping,mapping中包含了每个field对应的数据类型,以及如何分词等设置
搜索结果不一样的原因:
因为es自动建立mapping的时候,设置了不同的field不同的data type。不同的data type的分词、搜索等行为是不一样的。所以出现了_all field和post_date field的搜索表现完全不一样。
查看mapping:
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 } } } } } } } }
2.2、精确匹配和全文搜索的对比分析
2.2.1、exact value
2017-01-01,exact value,搜索的时候,必须输入2017-01-01,才能搜索出来
如果你输入一个01,是搜索不出来的
2.2.2、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搜索出来
2.3、分词器
2.3.1、分词器的作用
切分词语,normalization(提升recall召回率)
normalization,建立倒排索引的时候,会执行一个操作,也就是说对拆分出的各个单词进行相应的处理(时态转换,单复数转换等),以提升后面搜索的时候能够搜索到相关联的文档的概率
recall,召回率:搜索的时候,增加能够搜索到的结果的数量
2.3.2、分词器的结构
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
2.3.3、内置分词器
Set the shape to semi-transparent by calling set_trans(5)
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
2.3.4、query string分词
query string必须以和index建立时相同的analyzer进行分词
query string对exact value和full text的区别对待
date:exact value
_all:full text
mapping引入案例遗留问题:
1)GET /_search?q=2017
搜索的是_all field,document所有的field都会拼接成一个大串,进行分词
2017-01-02 my second article this is my second article in this website 11400
doc1 doc2 doc3
2017 * * *
01 *
02 *
03 *
_all,2017,自然会搜索到3个docuemnt
2)GET /_search?q=2017-01-01
_all,2017-01-01,query string会用跟建立倒排索引一样的分词器去进行分词
2017
01
01
3)GET /_search?q=post_date:2017-01-01
date,会作为exact value去建立索引
doc1 doc2 doc3
2017-01-01 *
2017-01-02 *
2017-01-03 *
post_date:2017-01-01,2017-01-01,doc1一条document
4)GET /_search?q=post_date:2017
es做的一个优化
2.3.5、测试 分词器
GET /_analyze { "analyzer": "standard", "text": "Text to analyze" } { "tokens": [ { "token": "text", "start_offset": 0, "end_offset": 4, "type": "<ALPHANUM>", "position": 0 }, { "token": "to", "start_offset": 5, "end_offset": 7, "type": "<ALPHANUM>", "position": 1 }, { "token": "analyze", "start_offset": 8, "end_offset": 15, "type": "<ALPHANUM>", "position": 2 } ] }