1. 概述 1.1 ElasticStack特点
使用门槛低,开发周期短,上线快
性能好,查询快,实时展示结果
扩容方便,快速支撑增长迅猛的数据
1.2 ElasticStack各组件作用
**Beats
**:数据采集
LogStash
: 数据处理
ElasticSearch
(核心引擎): 数据存储、查询和分析
Kibana
: 数据探索与可视化分析
1.3 ElasticStack使用场景
1.4 ElasticStack安装启动
ElasticSearch
启动:解压到安装目录,启动bin/elasticsearch
(默认端口:http:\\localhost:9200
, 加参数-d
后台启动)
ElasticSearch
集群:
1 2 3 bin/elasticsearch -d bin/elasticsearch -Ehttp.port=8200 -Epath.data=node2 -d bin/elasticsearch -Ehttp.port=7200 -Epath.data=node3 -d
Kibana启动:解压到安装目录,启动bin/kibana
(默认端口:http:\\localhost:5601
)
1.5 ElasticSearch常见术语
Document
(文档):用户存储在ES中的数据文档
Index
(索引):由具有相同字段的文档列表组成
field
(字段):包含具体数据
Node
(节点):一个ES的实例,构成clister的单元
Cluster
(集群):对外服务的一个/多个节点
1.6 Document介绍
常用数据类型:字符串、数值型、布尔型、日期型、二进制、范围类型
每个文档都有一个唯一ID
标识。(可以自行指定,也可由ES自动生成)
元数据,用于标注文档的相关信息:
_index
:文档所在的索引名
_type
:文档所在的类型名(后续的版本中type这个概念将会被移除,也不允许一个索引中有多个类型)
_id
:文档唯一标识
_source
:文档的原始JSON数据,可从这获取每个字段的内容
_all
:整合所有字段内容到该字段。(默认禁用)
_version
:文档字段版本号,标识被操作了几次
Index
介绍:
索引中存储相同结构的文档,且每个index都有自己的Mapping定义,用于定义字段名和类型;
一个集群中可以有多个inex,类似于可以有多个table。
RESTful API
两种交互方式:
CURL命令行:curl -XPUT xxx
Kibana DevTools————PUT xxx{ }
Index API
: 用户创建、删除、获取索引配置等。
创建索引:
PUT /test_index
#创建一个名为test_index
的索引
查看索引:
GET _cat/indices
#查看所有的索引
删除索引:
DELETE /test_index
#删除名为test_index
的索引
创建文档
1 2 3 4 5 6 7 8 9 10 11 12 13 PUT /test_index/doc/1 { "username" :"alfred" , "age" :"24" } POST /test_index/doc { "username" :"buzhiding" , "age" :"1" }
查询文档:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 GET /test_index/doc/1 GET /test_index/doc/_search { "query" :{ "term" :{ "_id" :"1" } } }
批量操作文档:
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 POST _bulk {"index" :{"_index" :"test_index" ,"_type" :"doc" ,"_id" :"3" }} {"username" :"alfred" ,"age" :"20" } {"delete" :{"_index" :"test_index" ,"_type" :"doc" ,"_id" :"1" }} {"update" :{"_id" :"2" ,"_index" :"test_index" ,"_type" :"doc" }} {"doc" :{"age" :"30" }} GET _mget { "doc" :[ { "_index" :"test_index" , "_type" :"doc" , "_id" :"1" }, { "_index" :"test_index" , "_type" :"doc" , "_id" :"2" } ] }
删除文档:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 POST /test_index/doc/_delete_by_query { "query" :{ "match" :{ "username" :"buzhiding" } } } POST /test_index/doc/_delete_by_query { "query" :{ "match_all" :{} } }
2. ElasticSearch倒排索引与分词 2.1 倒排索引
正排索引和倒排索引
正排索引:文档ID —> 文档内容
倒排索引:单词—> 文档ID列表
倒排索引组成:(单词词典,倒排列表)
单词词典(Term Dictionary
)
记录所有文档的单词,记录了单词到倒排列表的关联信息,一般使用B+Tree
实现。
倒排列表(Posting List
)
记录单词对应的文档集合,由倒排索引项Posting List
组成。
倒排索引项:
文档ID
:用于获取原始信息。
词频TF
:记录该单词在该文档中的出现次数,用于计算相关性得分。
位置Position
:记录单词在文档中的分词位置(多个),用于词语搜索。
偏移Offset
:记录单词在文档的开始和结束位置,用于高亮显示。
2.2 分词Analysis 分词:将文本转换成一系列单词Term/Token
的过程,也可称作文本分析,ES中叫作:Analysis。
一些概念:
Token
(词元):全文搜索引擎会用某种算法对要建索引的文档进行分析, 从文档中提取出若干Token(词元)。
Tokenizer
(分词器):这些算法叫做Tokenizer(分词器)
Token Filter
(词元处理器):这些Token会被进一步处理, 比如转成小写等, 这些处理算法被称为TokenFilter(词元处理器)
Term
(词):被处理后的结果被称为Term(词)
Character Filter
(字符过滤器):文本被Tokenizer处理前可能要做一些预处理, 比如去掉里面的HTML标记, 这些处理的算法被称为Character Filter(字符过滤器)
Analyzer
(分析器):这整个的分析算法被称为Analyzer(分析器),由Tokenizer(分词器)和Filter(过滤器)组成
ES有很多内置Analyzer
,比如:
standard
:按单词边界划分、支持多语言、小写处理、移除大部分标点符号,支持停用词
whitespace
:空格为分隔符
simple
:按非字母划分、小写处理
stop
:类似简单分词器,同时支持移除停用词(the、an、的、这等)
keyword
:不分词
pattern
:通过正则表达式自定义分隔符,默认\w+,即:非字词的符号作为分隔符
第三方analyzer插件:常用的中文分词器 有:
IK:实现中英文分词,支持多模式,可自定义词库,支持热更新分词词典。
jieba。python中流行,支持繁体分词、并行分词,可自定义词典、词性标记等。
ES提供了一个测试分词的API接口,使用endpoint:_analyze
,不指定分词时,会使用默认的standard
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 POST _analyze { "analyzer" :"standard" , "text" :"hello world!" } POST test_index/_analyze { "field" :"username" , "text" :"hello world!" } POST _analyze { "tokenizer" :"standard" , "filter" :["lowercase" ], "text" :"Hello World!" }
3. ElasticSearch的Mapping 3.1 Mapping简介 Mapping:类似于数据库中的表结构
主要作用如下:
定义Index
下的Field Name
;
定义Field
的类型,如:数值型、字符串型、布尔型等;
定义倒排索引的相关配置,如:是否有索引,记录position等。
获取一个mapping
,使用endpoint:_mapping
,例如:
3.2 自定义Mapping
使用mappings
进行自定义mapping
。
Mapping
中的字段类型一旦设定之后,禁止直接修改 。
因为Luence
事先的倒排索引生成后不能修改。
如果一定要改,可以重新建立新的索引,然后对应修改mapping
,之后将之前的数据进行reindex
操作,导入新的文档。
自定义mapping
时允许新增字段。通过dynamic
参数进行控制字段的新增,dynamic
有三种配置:
true
:默认配置,允许自动新增字段;
false
:不允许自动新增字段,文档可以正常写入,但不能进行查询等操作;
strict
:严格模式。文档不能写入,写入会报错。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 PUT my_index { "mappings" :{ "doc" :{ "dynamic" :false , "properties" :{ "title" :{ "type" :"text" }, "name" :{ "type" :"keyword" }, "age" :{ "type" :"integer" } } } } }
3.3 copy_to的使用 将该字段的值复制到目标字段,类似于6.0版本之前的_all
的作用。且不会出现在_source
,一般只用来进行搜索。
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 37 38 39 40 41 PUT my_index { "mappings" :{ "doc" :{ "properties" :{ "first_name" :{ "type" :"text" , "copy_to" :"full_name" }, "last_name" :{ "type" :"text" , "copy_to" :"full_name" }, "full_name" :{ "type" :"text" } } } } } PUT my_index/doc/1 { "first_name" :"John" , "last_name" :"Smith" } GET my_index/_search { "query" :{ "match" :{ "full_name" :{ "query" :"John Smith" , "operator" :"and" } } } }
3.4 index参数的使用 控制当前字段是否为索引,默认true
,当设置为false
的时候,不进行记录,此时该字段不能被搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 PUT my_index { "mappings" :{ "doc" :{ "properties" :{ "cookie" :{ "type" :"text" , "index" :false } } } } }
此时在进行数据写入和查询,不能进行该字段搜索。一般用来进行不想被查询的私密信息设置,如身份证号,电话号码等:
1 2 3 4 5 PUT my_index/doc/1 { "cookie" :"name=alfred" }
3.5 index_options参数的使用: 控制倒排索引记录的内容,有如下四种配置:
docs
:只记录文档ID
freqs
:记录文档ID和词频TF
positions
:记录文档ID、词频TF和分词位置
offsets
:记录文档ID、词频TF、分词位置和偏移
其中:text类型默认的配置是positions,其他的比如integer等类型默认为docs,目的是为了节省空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 PUT my_index { "mappings" :{ "doc" :{ "properties" :{ "cookie" :{ "type" :"text" , "index_options" :"offsets" } } } } }
3.6 null_value参数的使用: 当字段遇到空值null
时的处理策略。默认为null
,即跳过。此时ES会忽略该值,可通过修改进行默认值的修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 PUT my_index { "mappings" :{ "doc" :{ "properties" :{ "cookie" :{ "type" :"keyword" , "null_value" :"NULL" } } } } }
3.7 Field字段的数据类型:
核心数据类型
字符串型:text
(分词),keyword
(不分词)
数值型:long,integer,short,byte,double,float,half_float,scaled_float
日期类型:date
布尔类型:boolean
二进制类型:binary
范围类型:integer_range,float_range,long_range,double_range,date_range
复杂数据类型
数组类型:array
对象类型:object
嵌套类型:nested object
地理位置数据类型
点:geo-point
形状:geo-shape
专用类型
记录ip地址:ip
实现自动补全:completion
记录分词数:token_count
记录字符串hash值:murmur3
perclator
join
多字段特性:
ES允许对同一个字段采用不同的配置,如:分词。举例:对一个人名实现拼音搜索,只需要在人名字段中新增一个子字段pinyin即可。
3.8 ES的自动类型识别:
Dynamic Mapping:
ES可以自动识别文档字段类型,从而降低用户使用成本。
1 2 3 4 5 6 PUT my_index/doc/1 { "username" :"alfred" , "age" :20 }
ES依靠JSON文档的字段类型实现自动识别字段类型:
JSON类型
ElasticSearch类型
null
忽略
boolean
boolean
浮点类型
float
整数类型
long
object
object
array
由第一个非null的值的类型决定
String
匹配为日期,则为date类型(默认开启) 匹配为数字,则为long类型/float类型(默认关闭) 都未匹配,则设为text类型,并附带keyword子字段
验证ES的字段类型自动识别:
1 2 3 4 5 6 7 8 9 10 11 12 PUT my_index/doc/1 { "username" :"alfred" , "age" :20, "bitrh" :"1998-10-10" , "married" :false , "year" :"18" "tags" :["boy" ,"fashion" ], "money" :100.1 }
3.9 ES中日期类型和数字的自动识别: ES中可自行配置日期的格式,默认:[“strict_date_optional_time
“,”yyyy/MM/dd HH:mm:ss Z
|| yyyy/MM/dd z
“]
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 37 38 39 40 41 42 43 44 45 PUT my_index { "mappings" :{ "doc" :{ "dynamic_date_formats" :["MM/dd/yyyy" ] } } } PUT my_index/doc/1 { "create_time" :"01/01/2019" } PUT my_index { "mappings" :{ "doc" :{ "date_detection" :false } } } PUT my_index/doc/1 { "create_time" :"01/01/2019" } PUT my_index { "mappings" :{ "doc" :{ "numeric_detection" :true } } } PUT mu_index/doc/1 { "year" :"18" , "money" :"100.1" }
3.10 ES中根据自动识别的数据类型,动态生成字符类型 例:
字符串类型都设为keyword类型(不分词)
以message开头的字段都设为text类型(分词)
以long_开头的字段都设为long类型
自动匹配为double的类型都设为float类型。(为了节省空间)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 PUT test_index { "mappings" :{ "doc" :{ "dynamic_template" :[ { "strings" :{ "match_mapping_type" :"string" , "mapping" :{ "type" :"keyword" } } } ] } } }
匹配规则 的参数:
match_mapping_type
:匹配ES自动识别的字段类型,如boolean、long、string等
match
、unmatch
:匹配字段名,比如”match”:”message*” ===>以message开头的数据
path_match
、path_unmatch
:匹配路径
3.11 自定义mapping的操作步骤
写入一条文档到ES的临时索引中,获取(复制)ES自动生成的mapping
修改获得的mapping,并在其中自定义相关配置
使用修改后的mapping创建实际所需索引。
4. ElasticSearch的Search API 在ES中,为了实现对存储的数据进行查询分析,使用endpoint
:**_search
**。
实现对所有索引的泛查询:GET /_search
实现对一个索引的单独查询:GET /my_index/_search
实现对多个索引的指定查询:GET /my_index1,my_index2/_search
实现对符合指定要求的索引进行查询:GET /my_*/_search
在进行查询的时候,主要有两种方式:(URI Search
,Request Body Search
)
**URI Search
**:操作简单,直接通过命令行方便测试,但仅包含部分查询语法;
如:GET /my_index/_search?q=username:alfred
**Request Body Search
**:ES提供的完备查询语法,使用Query DSL(Domain Specific Language)
进行查询
1 2 3 4 5 6 7 8 9 GET /my_index/_search { "query" :{ "match" :{ "username" :"alfred" } } }
4.1 URI Search
通过url query
参数实现搜索,常用参数有:
**q
**:指定查询的语句,使用query string syntax语法
**df
**:q中不指定字段时默认查询的字段(在不指定的时候默认查询所有字段)
**sort
**:排序
**timeout
**:指定超时时间,默认不超时
**from,size
**:用于分页
举例:
GET my_index/_search?q=alfred&df=username&sort=age:asc&from=4&size=10&timeout=1s
解释:查询索引my_index
中username
字段中包含alfred
的文档,结果按age
字段升序排列
,返回第5-14
个文档,若超过1s
未结束,则以超时结束。
query string syntax
语法
前置内容:term:单词
,phrase:词语
。
单词与词语语法:
单词:alfred way
等价于alfred
OR way
词语:"alfred way"
语句查询,要求先后顺序
泛查询:不指定字段,会在所有字段中去匹配其单词
指定字段查询:指定字段,在指定字段中匹配单词
Group分组设定,使用括号指定匹配的规则
举例:GET my_index/_search?q=username:(alfred OR way)AND lee
4.1.1 URI Search API
泛查询:
1 2 3 4 GET my_index/_search?q=alfred { "profile" :true }
指定字段查询:
1 2 3 4 5 6 7 8 9 10 11 12 GET my_index/_search?q=username:alfred GET my_index/_search?q=username:alfred way GET my_index/_search?q=username:"alfred way" GET my_index/_search?q=username:(alfred way)
布尔操作符AND(&&)、OR(||)、NOT(!)、+(must)、-(must_not)
1 2 3 4 5 6 7 8 9 10 11 GET my_index/_search?q=username:(alfred NOT way) GET my_index/_search?q=username:(way +lee -alfred) GET my_index/_search?q=username:((lee && !alfred) || (way && lee && !alfred)) GET my_index/_search?q=username:(way %2Blee -alfred)
范围查询(支持数值和日期)
区间写法:闭区间使用[]
,开区间使用{}
age:[1 TO 10]
# 1<= age <=10
age:[1 TO 10}
# 1<= age <10
age:[1 TO ]
# age >=1
age:[* TO 10]
# age <=10
算数符号写法:
age:>=1
age:(>=1 && <= 10) / age:(+ >= 1 + <= 10)
还可以对日期进行范围查询,注意:年/月是从1月1号/1号开始算的:
1 2 3 4 5 6 7 8 GET my_index/_search?q=username:alfred age>20 GET my_index/_search?q=username:alfred AND age>20 GET my_index/_search?q=birth:(>1985 AND < 1990)
通配符查询
?
代表一个字符,*
代表0个或多个字符,如:name:a?lfred
或name:a*d
或name:alfred*
注意:通配符匹配的执行效率较低,且占用内存较多,不建议使用,如果没有特殊要求,也不要将?或者*放在最前面,因为意味着要匹配所有文档,可能会造成OOM。
正则表达式/模糊匹配/近似度查询
正则表达式:举例:/[a]?l.*/
模糊匹配:fuzzy query
近似度查询:proximity search
1 2 3 4 5 GET my_index/_search?q=username:alfred~1 GET my_index/_search?q=username:"alfred way" ~5
使用场景常见于用户输入词的纠错中。
4.2 Request Body Search ES自带的完备查询语句,将查询语句通过http request body
发送到ES,主要参数有:
query
:符合Query DSL
语法的查询条件
from,size
timeout
sort
Query DSL
语法:
基于JSON
定义的查询语言,主要包含两个类型:
字段类查询————如:term
,match
,range
等。只针对一个字段进行查询
复合查询————如:bool
查询等。包含一个/多个字段类查询/符合查询语句
4.2.1 字段类查询-全文匹配 针对text
类型的字段进行全文检索,会对查询语句进行“先分词再查询”处理,如:match
、match_phrase
等
4.2.1.1 match query
对字段进行全文检索(最基本和最常用的查询类型),举例:
1 2 3 4 5 6 7 8 GET my_index/_search { "query" :{ "match" :{ "username" :"alfred way" } } }
从结果,可以返回匹配文件总数,返回文档列表,_score相关性得分等。 一般的执行流程为: 1.对查询语句分词==>2.根据字段的倒排索引列表,进行匹配算分==>3.汇总得分==>4.根据得分排序,返回匹配文档
使用operator
参数,可以控制单词间关系,有and/or
:
1 2 3 4 5 6 7 8 9 10 GET my_index/_search { "query" :{ "match" :{ "username" :"alfred way" , "operator" :"and" } } }
使用minimum_should_match
参数控制需匹配的单词数
1 2 3 4 5 6 7 8 9 10 GET my_index/_search { "query" :{ "match" :{ "username" :"alfred way" , "minimum_should_match" :"2" } } }
4.2.1.2 相关性算分,其本质就是一个排序问题
计算文档与待查询语句之间的相关度,一般有四个重要概念:
Term Frequency
词频(正相关)
Document Frequency
文档频率(负相关)
Inverse Term Frequency
逆文本频率(正相关)
Field-length Norm
文档长度(负相关)
目前ES有两个相关性算分的模型:
TF/IDF
模型:经典模型。
BM25
模型:5.x版本后的默认模型,是对TF/IDF的优化模型。
TF/IDF
模型:在使用kibana进行查询时,使用explain参数,可以查看具体的计算方法。
1 2 3 4 5 6 7 8 9 10 GET my_index/_search { "explain" :true , "query" :{ "match" :{ "username" :"alfred" } } }
注意:ES计算相关性得分是根据shard
进行的,即分片的分数计算相互独立,所以在使用的时候要注意分片数,可以通过设定分片数为1来避免这个问题,主要是为了观察,不代表之后所有的分片全都设为1。一般放在创建索引后,未加数据之前。
1 2 3 4 5 6 7 PUT my_index { "settings" :{ "number_of_shards" :"1" } }
BM25模型。5.x版本后的默认模型,是对TF/IDF的优化模型。
best match,25
指:迭代了25次才计算。BM25的使用,降低了TF/IDF中因为TF过大导致的负面影响,在BM25中,一个单词的TF一直增长,到一定程度就趋于0变化。
4.2.1.3 match phrase query 对字段做全文检索,有顺序要求。
使用match——phrase
查询词语
1 2 3 4 5 6 7 8 GET my_index/_search { "query" :{ "match_phrase" :{ "job" :"java engineer" } } }
通过使用slop
参数,可以控制单词间间隔:
1 2 3 4 5 6 7 8 9 10 11 GET my_index/_search { "query" :{ "match_phrase" :{ "job" :{ "query" :"java engineer" , "slop" :"1" } } } }
4.2.1.4 query string query 类似于URI Search
中的q参数查询,举例:
使用query_string
查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 GET my_index/_search { "query" :{ "query_string" :{ "default_field" :"username" , "query" :{alfred AND way" } } } # #* 或 */ GET my_index/_search { " query":{ " query_string":{ " fileds":[" username"," job"], " query":" alfred OR (java AND ruby)" } } }
4.2.1.5 simple query string query 类似于query string
,但会忽略错误的查询语法,且仅支持部分查询语句。使用+,|,-
分别代替AND,OR,NOT
。
使用simple query string query1 2 3 4 5 6 7 8 9 GET my_index/_search { "query" :{ "simple_query_string" :{ "fields" :[username], "query" :"alfred +way" } } }
4.2.2 字段类查询-单词匹配 4.2.2.1 term/terms query 将待查询语句作为整个单词进行查询,不做分词处理,举例:
使用term进行单查询
1 2 3 4 5 6 7 8 GET my_index/_search { "query" :{ "term" :{ "username" :"alfred" } } }
使用terms进行多查询
1 2 3 4 5 6 7 8 GET my_index/_search { "query" :{ "terms" :{ "username" :["alfred" ,"way" ] } } }
此时如果直接使用alfred way
作为username
查询条件,是不会返回任何文档的。因为在username
的倒排索引列表中,存在"alfred"
和"way"
的索引,但是不存在"alfred way"
的索引。
4.2.2.2 range query
范围查询,主要针对数值类型和日期类型。
gt
: greater than 大于
gte
: greate than or equal to 大于等于
lt
: less than 小于
lte
: less than or equal to 小于等于
对数值的查询
1 2 3 4 5 6 7 8 9 10 11 12 GET my_index/_search { "query" :{ "range" :{ "age" :{ "gte" :10, "lte" :20 } } } }
对日期的查询
1 2 3 4 5 6 7 8 9 10 11 12 GET my_index/_search { "query" :{ "range" :{ "birth" :{ "lte" :"1988-01-01" } } } }
Date Math
类型 :针对日期提供的一种更友好的计算方式。 当前时间用now
代替,具体时间的引用,需要使用||
间隔。年、月、日、时、分、秒跟date
一致:y、M、w、d、h、m、s
。 举例:
1 2 3 4 5 now+1h => 2019-01-02 13:00:00 now-1h => 2019-01-02 11:00:00 now-1h/d => 2019-01-02 00:00:00 2019-01-01||+1M/d => 2019-02-01 00:00:00
4.2.3 复合查询 包含一个/多个字段类查询/符合查询语句
4.2.3.1 constant_score query
constant_score query
: 将内部的查询结果文档得分全部设定为1或boost的值。返回的相关性得分全部为1或boost
1 2 3 4 5 6 7 8 9 10 11 GET my_index/_Search { "query" :{ "constant_score" :{ "match" :{ "username" :"alfred" } } } }
4.2.3.2 bool query bool query
: 由一个/多个布尔子句组成,主要包含以下四个:
filter
: 只过滤符合条件的文档,不计算相关性得分,返回的相关性得分全部为0;
ES
会对filter
进行智能缓存,因此执行效率较高,在做简单匹配查询且不考虑得分的时候没推荐使用filter
代替query
1 2 3 4 5 6 7 8 9 10 11 12 13 GET my_index/_search { "query" :{ "bool" :{ "filter" :[ "term" :{ "username" :"alfred" } ] } } }
must
: 文档必须符合must
中的所有条件,影响相关性得分;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 GET my_index/_search { "query" :{ "bool" :{ "must" :[ { "match" :{ "username" :"alfred" } }, { "match" :{ "job" :"specialist" } } ] } } }
must_not
: 文档必须排除must_not中的所有条件;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 GET my_index/_search { "query" :{ "bool" :{ "must" :[ { "match" :{ "job" :"java" } } ], "must_not" :[ { "match" :{ "job" :"ruby" } } ] } } }
should
: 文档可以符合should
中的条件,影响相关性得分,分为两种情况:同时配合minimum_should_match
控制满足调价你的个数/百分比。
bool
查询中只有should
,不包含must
的情况
bool查询中既有should,又包含must的情况,文档不必满足should中的条件,但是如果满足的话则会增加相关性得分。
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 37 38 39 GET my_index/_search { "query" :{ "bool" :{ "should" :[ { "term" :{"job" :"java" } }, { "term" :{"job" :"ruby" } } { "term" :{"job" :"specialist" } } ], "minimum_should_match" :2 } } } GET my_index/_search { "query" :{ "bool" :{ "should" :[ { "term" :{"job" :"ruby" } } ], "must" :[ { "term" :{"usernmae" :"alfred" } } ] } } }
当一个查询语句位于query或filter上下文的时候,ES的执行结果也不同。
-
-
-
query
查找和查询语句最匹配的文档, 并对所有文档计算相关性得分
query bool中的:must/should
filter
查找和查询语句最匹配的文档
bool中的:filter/must_not constant_score中的:filter
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 GET my_index/_search { "query" :{ "bool" :{ "must" :[ { "term" :{"title" :"Search" } }, { "term" :{"content" :"ElasticSearch" } } ], "filter" :[ { "term" :{"status" :"published" } }, { "range" :{ "publish_date" :{ "gte" :"2015-01-01" } } } ] } } }
4.2.3.3 count API count API
: 获取符合条件的文档书,使用endpoint:_count
。
1 2 3 4 5 6 7 8 9 GET my_index/_count { "query" :{ "match" :{ "username" :"alfred" } } }
4.2.3.4 Source Filtering Source Filtering
: 过滤返回结果中的_source
中的字段,主要由以下两种方式:
GET my_index/_search?_source=username #url参数
使用Request Body Search:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 GET my_index/_search { "_source" :false } GET my_index/_search { "_source" :["username" ,"age" ] } GET my_index/_search { "_source" :{ "includes" :"*I*" , "encludes" :"birth" } }
原文链接: http://chaooo.github.io/2018/11/12/elastic-base.html
版权声明: 转载请注明出处.