- 对于
大并发更新
,不带update
- 对于
大并发查询偶尔更新
,带update
;对比更新,重新计算分配规则
- POST更新文档,带有_update
- 删除文档或索引
DELETE customer/external/1
DELETE customer
#注:elasticsearch并没有提供删除类型的操作,只提供了删除索引和文档的操作。
#实例:删除整个costomer索引数据
#删除前,所有的索引
get /_cat/indices
green open .kibana_task_manager_1 DhtDmKrsRDOUHPJm1EFVqQ 1 0 2 0 31.3kb 31.3kb
green open .apm-agent-configuration vxzRbo9sQ1SvMtGkx6aAHQ 1 0 0 0 283b 283b
green open .kibana_1 rdJ5pejQSKWjKxRtx-EIkQ 1 0 8 3 28.8kb 28.8kb
yellow open customer mG9XiCQISPmfBAmL1BPqIw 1 1 9 1 8.6kb 8.6kb
#删除 “customer”索引
DELTE /customer
#响应
{
“acknowledged”: true
}
#删除后,所有的索引/_cat/indices
green open .kibana_task_manager_1 DhtDmKrsRDOUHPJm1EFVqQ 1 0 2 0 31.3kb 31.3kb
green open .apm-agent-configuration vxzRbo9sQ1SvMtGkx6aAHQ 1 0 0 0 283b 283b
green open .kibana_1 rdJ5pejQSKWjKxRtx-EIkQ 1 0 8 3 28.8kb 28.8kb
- ES的批量操作——bulk
#匹配导入数据
post /customer/external/_bulk
{“index”:{“_id”:“1”}}#两行为一个整体
{“name”:“a”}#真正的数据
{“index”:{“_id”:“2”}}#两行为一个整体
{“name”:“b”}#真正的数据
#语法格式:
post /xxxxx/xxxxx/_bulk
{action:{metadata}}\n
{request body }\n
{action:{metadata}}\n
{request body }\n
这里的批量操作,当发生某一条执行发生失败
时,其他的数据仍然能够接着执行
,也就是说彼此之间是独立的
。
bulk api以此按顺序执行所有的action(动作)。如果一个单个的动作因任何原因失败,它将继续处理它后面剩余的动作。当bulk api返回时,它将提供每个动作的状态(与发送的顺序相同),所以您可以检查是否一个指定的动作是否失败了。
#实例1: 执行多条数据
POST /customer/external/_bulk
{“index”:{“_id”:“1”}}
{“name”:“John Doe”}
{“index”:{“_id”:“2”}}
{“name”:“John Doe”}
#保存操作,指定了索引、id,真正的数据未name:xxx
#执行结果
{
“took” : 318, #花费了多少ms
“errors” : false, #没有发生任何错误
“items” : [ #每个数据的结果
{
“index” : { #保存
“_index” : “customer”, #索引
“_type” : “external”, #类型
“_id” : “1”, #文档
“_version” : 1, #版本
“result” : “created”, #创建
“_shards” : {
“total” : 2,
“successful” : 1,
“failed” : 0
},
“_seq_no” : 0,
“_primary_term” : 1,
“status” : 201 #新建完成
}
},
{
“index” : { #第二条记录
“_index” : “customer”,
“_type” : “external”,
“_id” : “2”,
“_version” : 1,
“result” : “created”,
“_shards” : {
“total” : 2,
“successful” : 1,
“failed” : 0
},
“_seq_no” : 1,
“_primary_term” : 1,
“status” : 201
}
}
]
}
#实例2:对于整个索引执行批量操作
POST /_bulk
{“delete”:{“_index”:“website”,“_type”:“blog”,“_id”:“123”}}#删除操作
{“create”:{“_index”:“website”,“_type”:“blog”,“_id”:“123”}}#保存操作,下面是数据
{“title”:“my first blog post”}
{“index”:{“_index”:“website”,“_type”:“blog”}}#保存操作,下面的是数据
{“title”:“my second blog post”}
{“update”:{“_index”:“website”,“_type”:“blog”,“_id”:“123”}}#更新操作
{“doc”:{“title”:“my updated blog post”}}
#指定操作,索引,类型,id
#运行结果:
{
“took” : 414,
“errors” : false,
“items” : [
{
“delete” : {
“_index” : “website”,
“_type” : “blog”,
“_id” : “123”,
“_version” : 1,
“result” : “not_found”,
“_shards” : {
“total” : 2,
“successful” : 1,
“failed” : 0
},
“_seq_no” : 0,
“_primary_term” : 1,
“status” : 404
}
},
{
“create” : {
“_index” : “website”,
“_type” : “blog”,
“_id” : “123”,
“_version” : 2,
“result” : “created”,
“_shards” : {
“total” : 2,
“successful” : 1,
“failed” : 0
},
“_seq_no” : 1,
“_primary_term” : 1,
“status” : 201
}
},
{
“index” : {
“_index” : “website”,
“_type” : “blog”,
“_id” : “AOpgO3wB3UIR4wi8SrO8”,
“_version” : 1,
“result” : “created”,
“_shards” : {
“total” : 2,
“successful” : 1,
“failed” : 0
},
“_seq_no” : 2,
“_primary_term” : 1,
“status” : 201
}
},
{
“update” : {
“_index” : “website”,
“_type” : “blog”,
“_id” : “123”,
“_version” : 3,
“result” : “updated”,
“_shards” : {
“total” : 2,
“successful” : 1,
“failed” : 0
},
“_seq_no” : 3,
“_primary_term” : 1,
“status” : 200
}
}
]
}
- 样本测试数据
准备了一份顾客银行账户信息的虚构的JSON文档样本。每个文档都有下列的schema(模式)。
{
“account_number”: 1,
“balance”: 39225,
“firstname”: “Amber”,
“lastname”: “Duke”,
“age”: 32,
“gender”: “M”,
“address”: “880 Holmes Lane”,
“employer”: “Pyrami”,
“email”: “amberduke@pyrami.com”,
“city”: “Brogan”,
“state”: “IL”
}
https://gitee.com/xlh_blog/common_content/blob/master/es%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE.json
;导入测试数据
POST bank/account/_bulk
#上面的数据
get /_cat/indices #刚导入了1000条
- 让Docker每次启动都自动启动ES
sudo docker update 【实例ID】 --restart=always
[root@s1 elasticsearch]# sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c43fff82773 kibana:7.4.2 “/usr/local/bin/dumb…” 2 hours ago Up 2 hours 0.0.0.0:5601->5601/tcp, :::5601->5601/tcp kibana
4fe4e202abf1 elasticsearch:7.4.2 “/usr/local/bin/dock…” 2 hours ago Up 2 hours 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp elasticsearch
879b641ebe6c redis “docker-entrypoint.s…” 11 days ago Up 2 hours 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redis
b2b889f90cd9 mysql:5.7 “docker-entrypoint.s…” 11 days ago Up 2 hours 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql
[root@s1 elasticsearch]# sudo docker update 5c4 --restart=always
5c4
[root@s1 elasticsearch]# sudo docker update 4fe --restart=always
4fe
官方API:
https://www.elastic.co/guide/en/elasticsearch/reference/7.x/search-your-data.html
1、search Api
- 通过REST request uri 发送搜索参数 (
uri +检索参数
);
- 通过REST request body 来发送它们(
uri+请求体
);
- 请求参数方式检索
检索bank索引中查询全部,并按account_number升序排序;
检索了1000条数据,但是根据相关性算法,只返回10条
GET bank/_search?q=*&sort=account_number:asc
q=* 查询所有
sort 排序字段
asc升序
检索bank下所有信息,包括type和docs
GET bank/_search
返回格式
took – 花费多少ms搜索
timed_out – 是否超时
_shards – 多少分片被搜索了,以及多少成功/失败的搜索分片
max_score –文档相关性最高得分
hits.total.value - 多少匹配文档被找到
hits.sort - 结果的排序key,没有的话按照score排序
hits._score - 相关得分 (not applicable when using match_all)
- uri+请求体进行检索
GET /bank/_search
{
“query”: { “match_all”: {} },
“sort”: [
{ “account_number”: “asc” },
{“balance”:“desc”}
]
}
2、Query DSL
什么get的请求体叫query DSL
- 基本语法格式
Elasticsearch提供了一个可以执行查询的Json风格的DSL
(domain-specific language领域特定语言)。这个被称为Query DSL,该查询语言非常全面。
- 典型结构
QUERY_NAME:{
ARGUMENT:VALUE,
ARGUMENT:VALUE,
…
}
如果针对于某个字段,那么它的结构如下:
{
QUERY_NAME:{
FIELD_NAME:{
ARGUMENT:VALUE,
ARGUMENT:VALUE,…
}
}
}
- 示例
GET bank/_search
{
“query”: { #查询形式
“match_all”: {} #查询所有
},
“from”: 0, #开始位置
“size”: 5, #显示数
“_source”:[“balance”],#返回部分字段
“sort”: [ #排序
{
“account_number”: {
“order”: “desc”
}
}
]
}
_source为要返回的字段
3、match匹配查询
- 基本类型(
非字符串
),精确控制
GET bank/_search
{
“query”: {
“match”: {
“account_number”: “999”
}
}
}
查询结果
{
“took” : 8,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 1,
“relation” : “eq”
},
“max_score” : 1.0,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “999”,
“_score” : 1.0,
“_source” : {
“account_number” : 999,
“balance” : 6087,
“firstname” : “Dorothy”,
“lastname” : “Barron”,
“age” : 22,
“gender” : “F”,
“address” : “499 Laurel Avenue”,
“employer” : “Xurban”,
“email” : “dorothybarron@xurban.com”,
“city” : “Belvoir”,
“state” : “CA”
}
}
]
}
}
字符串
,全文检索
GET bank/_search
{
“query”: {
“match”: {
“address”: “kings” #字符串
}
}
}
全文检索,最终会按照评分进行排序,会对检索条件进行分词匹配
。
{
“took” : 9,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 2,
“relation” : “eq”
},
“max_score” : 5.9908285,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “20”,
“_score” : 5.9908285,
“_source” : {
“account_number” : 20,
“balance” : 16418,
“firstname” : “Elinor”,
“lastname” : “Ratliff”,
“age” : 36,
“gender” : “M”,
“address” : “282 Kings Place”, #分词匹配
“employer” : “Scentric”,
“email” : “elinorratliff@scentric.com”,
“city” : “Ribera”,
“state” : “WA”
}
},
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “722”,
“_score” : 5.9908285,
“_source” : {
“account_number” : 722,
“balance” : 27256,
“firstname” : “Roberts”,
“lastname” : “Beasley”,
“age” : 34,
“gender” : “F”,
“address” : “305 Kings Hwy”,#分词匹配
“employer” : “Quintity”,
“email” : “robertsbeasley@quintity.com”,
“city” : “Hayden”,
“state” : “PA”
}
}
]
}
}
4、match_phrase 【短句匹配】
- match_phrase
将需要匹配的值当成一整个单词(不分词)
进行检索
前面的是包含mill或road就查出来,我们现在要都包含才查出
GET bank/_search
{
“query”: {
“match_phrase”: {
“address”: “mill road”
}
}
}
查处address中包含mill road的所有记录,并给出相关性得分
{
“took” : 50,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 1,
“relation” : “eq”
},
“max_score” : 8.926605,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “970”,
“_score” : 8.926605,
“_source” : {
“account_number” : 970,
“balance” : 19648,
“firstname” : “Forbes”,
“lastname” : “Wallace”,
“age” : 28,
“gender” : “M”,
“address” : “990 Mill Road”,
“employer” : “Pheast”,
“email” : “forbeswallace@pheast.com”,
“city” : “Lopezo”,
“state” : “AK”
}
}
]
}
}
match_phrase和match的区别
,观察如下实例
GET bank/_search
{
“query”: {
“match_phrase”: {
“address”: “990 Mill”
}
}
}
结果
{
“took” : 1,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 1,
“relation” : “eq”
},
“max_score” : 10.806405,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “970”,
“_score” : 10.806405,
“_source” : {
“account_number” : 970,
“balance” : 19648,
“firstname” : “Forbes”,
“lastname” : “Wallace”,
“age” : 28,
“gender” : “M”,
“address” : “990 Mill Road”, #
“employer” : “Pheast”,
“email” : “forbeswallace@pheast.com”,
“city” : “Lopezo”,
“state” : “AK”
}
}
]
}
}
使用match的keyword
GET bank/_search
{
“query”: {
“match”: {
“address.keyword”: “990 Mill”
}
}
}
查询结果,一条也未匹配到
{
“took” : 0,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 0,
“relation” : “eq”
},
“max_score” : null,
“hits” : [ ] #
}
}
修改匹配条件为“990 Mill Road”
GET bank/_search
{
“query”: {
“match”: {
“address.keyword”: “990 Mill Road”
}
}
}
修改匹配条件为“990 Mill Road”
{
“took” : 0,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 1,
“relation” : “eq”
},
“max_score” : 6.5032897,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “970”,
“_score” : 6.5032897,
“_source” : {
“account_number” : 970,
“balance” : 19648,
“firstname” : “Forbes”,
“lastname” : “Wallace”,
“age” : 28,
“gender” : “M”,
“address” : “990 Mill Road”, #
“employer” : “Pheast”,
“email” : “forbeswallace@pheast.com”,
“city” : “Lopezo”,
“state” : “AK”
}
}
]
}
}
查询出一条数据
{
“took” : 0,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 1,
“relation” : “eq”
},
“max_score” : 6.5032897,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “970”,
“_score” : 6.5032897,
“_source” : {
“account_number” : 970,
“balance” : 19648,
“firstname” : “Forbes”,
“lastname” : “Wallace”,
“age” : 28,
“gender” : “M”,
“address” : “990 Mill Road”,
“employer” : “Pheast”,
“email” : “forbeswallace@pheast.com”,
“city” : “Lopezo”,
“state” : “AK”
}
}
]
}
}
文本字段的匹配,使用keyword,匹配的条件就是要显示字段的全部值,要进行精确匹配的。
match_phrase是做短语匹配,只要文本中包含匹配条件,就能匹配到
。
5、multi_math【多字段匹配】
字段中或关系
,state或者address中包含mill
,并且在查询过程中,会对于查询条件进行分词。
GET bank/_search
{
“query”: {
“multi_match”: {
“query”: “mill”,
“fields”: [
“state”,
“address”
]
}
}
}
查询结果:
{
“took” : 28,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 4,
“relation” : “eq”
},
“max_score” : 5.4032025,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “970”,
“_score” : 5.4032025,
“_source” : {
“account_number” : 970,
“balance” : 19648,
“firstname” : “Forbes”,
“lastname” : “Wallace”,
“age” : 28,
“gender” : “M”,
“address” : “990 Mill Road”,
“employer” : “Pheast”,
“email” : “forbeswallace@pheast.com”,
“city” : “Lopezo”,
“state” : “AK”
}
},
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “136”,
“_score” : 5.4032025,
“_source” : {
“account_number” : 136,
“balance” : 45801,
“firstname” : “Winnie”,
“lastname” : “Holland”,
“age” : 38,
“gender” : “M”,
“address” : “198 Mill Lane”,
“employer” : “Neteria”,
“email” : “winnieholland@neteria.com”,
“city” : “Urie”,
“state” : “IL”
}
},
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “345”,
“_score” : 5.4032025,
“_source” : {
“account_number” : 345,
“balance” : 9812,
“firstname” : “Parker”,
“lastname” : “Hines”,
“age” : 38,
“gender” : “M”,
“address” : “715 Mill Avenue”,
“employer” : “Baluba”,
“email” : “parkerhines@baluba.com”,
“city” : “Blackgum”,
“state” : “KY”
}
},
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “472”,
“_score” : 5.4032025,
“_source” : {
“account_number” : 472,
“balance” : 25571,
“firstname” : “Lee”,
“lastname” : “Long”,
“age” : 32,
“gender” : “F”,
“address” : “288 Mill Street”,
“employer” : “Comverges”,
“email” : “leelong@comverges.com”,
“city” : “Movico”,
“state” : “MT”
}
}
]
}
}
6、bool用来做复合查询
复合语句可以合并,任何其他查询语句,包括符合语句。
这也就意味着,复合语句之间可以互相嵌套,可以表达非常复杂的逻辑。
- must:
- 必须达到must所列举的所有条件
- must_not:
- 必须不匹配must_not所列举的所有条件。
- should:
- 应该满足should所列举的条件。满足条件最好,不满足也可以,满足得分更高
- must 必须是指定的情况
实例:查询gender=m,并且
address=mill的数据
GET bank/_search
{
“query”:{
“bool”:{
“must”:[
{“match”:{“address”:“mill”}},
{“match”:{“gender”:“M”}}
]
}
}
}
结果
{
“took” : 83,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 3,
“relation” : “eq”
},
“max_score” : 6.0824604,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “970”,
“_score” : 6.0824604,
“_source” : {
“account_number” : 970,
“balance” : 19648,
“firstname” : “Forbes”,
“lastname” : “Wallace”,
“age” : 28,
“gender” : “M”,
“address” : “990 Mill Road”,
“employer” : “Pheast”,
“email” : “forbeswallace@pheast.com”,
“city” : “Lopezo”,
“state” : “AK”
}
},
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “136”,
“_score” : 6.0824604,
“_source” : {
“account_number” : 136,
“balance” : 45801,
“firstname” : “Winnie”,
“lastname” : “Holland”,
“age” : 38,
“gender” : “M”,#
“address” : “198 Mill Lane”,#
“employer” : “Neteria”,
“email” : “winnieholland@neteria.com”,
“city” : “Urie”,
“state” : “IL”
}
},
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “345”,
“_score” : 6.0824604,
“_source” : {
“account_number” : 345,
“balance” : 9812,
“firstname” : “Parker”,
“lastname” : “Hines”,
“age” : 38,
“gender” : “M”,#
“address” : “715 Mill Avenue”,#
“employer” : “Baluba”,
“email” : “parkerhines@baluba.com”,
“city” : “Blackgum”,
“state” : “KY”
}
}
]
}
}
- must_not 必须不是指定的情况
实例:查询gender=m,并且address=mill的数据,但是age不等于38的
GET bank/_search
{
“query”: {
“bool”: {
“must”: [
{ “match”: { “gender”: “M” }},
{ “match”: {“address”: “mill”}}
],
“must_not”: [
{ “match”: { “age”: “38” }}
]
}
}
}
结果
{
“took” : 8,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 1,
“relation” : “eq”
},
“max_score” : 6.0824604,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “970”,
“_score” : 6.0824604,
“_source” : {
“account_number” : 970,
“balance” : 19648,
“firstname” : “Forbes”,
“lastname” : “Wallace”,
“age” : 28,#
“gender” : “M”, #
“address” : “990 Mill Road”, #
“employer” : “Pheast”,
“email” : “forbeswallace@pheast.com”,
“city” : “Lopezo”,
“state” : “AK”
}
}
]
}
}
- should
应该达到should列举的条件,如果到达会增加相关文档的评分,并不会改变查询的结果。
如果query中只有should且只有一种匹配规则,那么should的条件就会被作为默认匹配条件二区改变查询结果。
实例:匹配lastName应该等于
Wallace的数据
GET bank/_search
{
“query”: {
“bool”: {
“must”: [
{
“match”: {
“gender”: “M”
}
},
{
“match”: {
“address”: “mill”
}
}
],
“must_not”: [
{
“match”: {
“age”: “18”
}
}
],
“should”: [
{
“match”: {
“lastname”: “Wallace”
}
}
]
}
}
}
查询结果:能够看到相关度越高,得分也越高。
{
“took” : 7,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 3,
“relation” : “eq”
},
“max_score” : 12.585751,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “970”,
“_score” : 12.585751,
“_source” : {
“account_number” : 970,
“balance” : 19648,
“firstname” : “Forbes”,
“lastname” : “Wallace”,#
“age” : 28,#
“gender” : “M”,#
“address” : “990 Mill Road”,#
“employer” : “Pheast”,
“email” : “forbeswallace@pheast.com”,
“city” : “Lopezo”,
“state” : “AK”
}
},
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “136”,
“_score” : 6.0824604,
“_source” : {
“account_number” : 136,
“balance” : 45801,
“firstname” : “Winnie”,
“lastname” : “Holland”,#
“age” : 38,#
“gender” : “M”,#
“address” : “198 Mill Lane”,#
“employer” : “Neteria”,
“email” : “winnieholland@neteria.com”,
“city” : “Urie”,
“state” : “IL”
}
},
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “345”,
“_score” : 6.0824604,
“_source” : {
“account_number” : 345,
“balance” : 9812,
“firstname” : “Parker”,
“lastname” : “Hines”,#
“age” : 38,#
“gender” : “M”,#
“address” : “715 Mill Avenue”,#
“employer” : “Baluba”,
“email” : “parkerhines@baluba.com”,
“city” : “Blackgum”,
“state” : “KY”
}
}
]
}
}
7、Filter【结果过滤】
上面的must和should影响相关性得分,而must_not仅仅是一个filter ,不贡献得分 must改为filter就使must不贡献得分。
如果只有filter条件的话,我们会发现得分都是0
。
一个key多个值可以用terms并不是所有的查询都需要产生分数,特别是哪些仅用于filtering过滤的文档。
为了不计算分数,elasticsearch会自动检查场景并且优化查询的执行。 不参与评分更快
GET bank/_search
{
“query”: {
“bool”: {
“must”: [
{ “match”: {“address”: “mill” } }
],
“filter”: { #query.bool.filter
“range”: {
“balance”: {
“gte”: “10000”,
“lte”: “20000”
}
}
}
}
}
}
这里先是查询所有匹配address=mill的文档,然后再根据10000<=balance<=20000进行过滤查询结果
{
“took” : 37,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 1,
“relation” : “eq”
},
“max_score” : 5.4032025, #
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “970”,
“_score” : 5.4032025,
“_source” : {
“account_number” : 970,
“balance” : 19648, #
“firstname” : “Forbes”,
“lastname” : “Wallace”,
“age” : 28,
“gender” : “M”,
“address” : “990 Mill Road”, #
“employer” : “Pheast”,
“email” : “forbeswallace@pheast.com”,
“city” : “Lopezo”,
“state” : “AK”
}
}
]
}
}
在boolean查询
中,must, should 和must_not 元素都被称为查询子句
。
文档是否符合每个“must”或“should”子句中的标准,决定了文档的“相关性得分”。
得分越高,文档越符合您的搜索条件
。
默认情况下,Elasticsearch返回根据这些相关性得分排序的文档。
“must_not”子句中的条件被视为“过滤器”。 它影响文档是否包含在结果中, 但不影响文档的评分方式。 还可以显式地指定任意过滤器来包含或排除基于结构化数据的文档。
filter在使用过程中,并不会计算相关性得分:
GET bank/_search
{
“query”: {
“bool”: {
“must”: [
{
“match”: {
“address”: “mill”
}
}
],
“filter”: {
“range”: {
“balance”: {
“gte”: “10000”,
“lte”: “20000”
}
}
}
}
}
}
#查询结果:
{
“took” : 1,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 213,
“relation” : “eq”
},
“max_score” : 0.0,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “20”,
“_score” : 0.0,
“_source” : {
“account_number” : 20,
“balance” : 16418,
“firstname” : “Elinor”,
“lastname” : “Ratliff”,
“age” : 36,
“gender” : “M”,
“address” : “282 Kings Place”,
“employer” : “Scentric”,
“email” : “elinorratliff@scentric.com”,
“city” : “Ribera”,
“state” : “WA”
}
},
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “37”,
“_score” : 0.0,
“_source” : {
“account_number” : 37,
“balance” : 18612,
“firstname” : “Mcgee”,
“lastname” : “Mooney”,
“age” : 39,
“gender” : “M”,
“address” : “826 Fillmore Place”,
“employer” : “Reversus”,
“email” : “mcgeemooney@reversus.com”,
“city” : “Tooleville”,
“state” : “OK”
}
},
#省略。。。
能看到所有文档的“_score” : 0.0
8、term
和match一样
。匹配某个属性的值。
全文检索字段(text字符串等)用match, 其他 非text字段匹配用term。
不要使用term来进行文本字段查询 es默认存储text值时用分词分析,所以要搜索text值,使用match
https://www.elastic.co/guide/en/elasticsearch/reference/7.6/query-dsl-term-query.html
- 字段.keyword:要一一匹配到
精确匹配
- match_phrase:子串包含即可 使用term匹配查询
短语匹配
GET bank/_search
{
“query”: {
“term”: {
“address”: “mill Road”
}
}
}
查询结果:
一条也没有匹配到
{
“took” : 6,.
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 0,
“relation” : “eq”
},
“max_score” : null,
“hits” : [ ]
}
}
而更换为match匹配时,能够匹配到32个文档
GET bank/_search
{
“query”: {
“match”: {
“address”: “mill Road”
}
}
}
结果:
{
“took” : 17,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 32,
“relation” : “eq”
},
“max_score” : 8.926605,
“hits” : [
{
“_index” : “bank”,
“_type” : “account”,
“_id” : “970”,
“_score” : 8.926605,
“_source” : {
“account_number” : 970,
“balance” : 19648,
“firstname” : “Forbes”,
“lastname” : “Wallace”,
“age” : 28,
“gender” : “M”,
“address” : “990 Mill Road”,
“employer” : “Pheast”,
“email” : “forbeswallace@pheast.com”,
“city” : “Lopezo”,
“state” : “AK”
}
},
#省略…
}
]
}
}
9、Aggregation(聚合)
聚合提供了从数据中分组
和提取
数据的能力。最简单的聚合方法大致等于SQL Group by和SQL聚合函数。
在elasticsearch中,执行搜索返回this(命中结果),并且同时返回聚合结果,把以响应中的所有hits(命中结果)分隔开的能力。
这是非常强大且有效的,你可以执行查询和多个聚合,并且在一次使用中得到各自的(任何一个的)返回结果,使用一次简洁和简化的API啦避免网络往返。
aggs:执行聚合。聚合语法如下:
“aggs”:{ # 聚合
“aggs_name这次聚合的名字,方便展示在结果集中”:{
“AGG_TYPE聚合的类型(avg,term,terms)”:{}
}
}
terms:看值的可能性分布
avg:看值的分布平均
- 例:搜索address中包含mill的所有人的年龄分布以及平均年龄,但不显示这些人的详情
分别为包含mill、,平均年龄、
GET bank/_search
{
“query”: { # 查询出包含mill的
“match”: {
“address”: “Mill”
}
},
“aggs”: { #基于查询聚合
“ageAgg”: { # 聚合的名字,随便起
“terms”: { # 看值的可能性分布
“field”: “age”,
“size”: 10
}
},
“ageAvg”: {
“avg”: { # 看age值的平均
“field”: “age”
}
},
“balanceAvg”: {
“avg”: { # 看balance的平均
“field”: “balance”
}
}
},
“size”: 0 # 不看详情,只看聚合结果
}
查询结果:
{
“took” : 2,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 4, // 命中4条
“relation” : “eq”
},
“max_score” : null,
“hits” : [ ]
},
“aggregations” : {
“ageAgg” : { // 第一个聚合的结果
“doc_count_error_upper_bound” : 0,
“sum_other_doc_count” : 0,
“buckets” : [
{
“key” : 38,
“doc_count” : 2
},
{
“key” : 28,
“doc_count” : 1
},
{
“key” : 32,
“doc_count” : 1
}
]
},
“ageAvg” : { // 第二个聚合的结果
“value” : 34.0
},
“balanceAvg” : { // 第三个聚合的结果
“value” : 25208.0
}
}
}
- 子聚合
按照年龄聚合,并且求这些年龄段的这些人的平均薪资
写到一个聚合里是基于上个聚合进行子聚合。
下面求每个age分布的平均balance
GET bank/_search
{
“query”: {
“match_all”: {} #查询所有
},
“aggs”: {
“ageAgg”: {
“terms”: { # 看分布
“field”: “age”, #字段
“size”: 100 #数量
},
“aggs”: { # 与terms并列 【子聚合】
“ageAvg”: { #平均
“avg”: {
“field”: “balance”
}
}
}
}
},
“size”: 0
}
输出结果
{
“took” : 49,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 1000,
“relation” : “eq”
},
“max_score” : null,
“hits” : [ ]
},
“aggregations” : {
“ageAgg” : {
“doc_count_error_upper_bound” : 0,
“sum_other_doc_count” : 0,
“buckets” : [
{
“key” : 31,
“doc_count” : 61,
“ageAvg” : {
“value” : 28312.918032786885
}
},
{
“key” : 39,
“doc_count” : 60,
“ageAvg” : {
“value” : 25269.583333333332
}
},
{
“key” : 26,
“doc_count” : 59,
“ageAvg” : {
“value” : 23194.813559322032
}
},
{
“key” : 32,
“doc_count” : 52,
“ageAvg” : {
“value” : 23951.346153846152
}
},
{
“key” : 35,
“doc_count” : 52,
“ageAvg” : {
“value” : 22136.69230769231
}
},
{
“key” : 36,
“doc_count” : 52,
“ageAvg” : {
“value” : 22174.71153846154
}
},
{
“key” : 22,
“doc_count” : 51,
“ageAvg” : {
“value” : 24731.07843137255
}
},
{
“key” : 28,
“doc_count” : 51,
“ageAvg” : {
“value” : 28273.882352941175
}
},
{
“key” : 33,
“doc_count” : 50,
“ageAvg” : {
“value” : 25093.94
}
},
{
“key” : 34,
“doc_count” : 49,
“ageAvg” : {
“value” : 26809.95918367347
}
},
{
“key” : 30,
“doc_count” : 47,
“ageAvg” : {
“value” : 22841.106382978724
}
},
{
“key” : 21,
“doc_count” : 46,
“ageAvg” : {
“value” : 26981.434782608696
}
},
{
“key” : 40,
“doc_count” : 45,
“ageAvg” : {
“value” : 27183.17777777778
}
},
{
“key” : 20,
“doc_count” : 44,
“ageAvg” : {
“value” : 27741.227272727272
}
},
{
“key” : 23,
“doc_count” : 42,
“ageAvg” : {
“value” : 27314.214285714286
}
},
{
“key” : 24,
“doc_count” : 42,
“ageAvg” : {
“value” : 28519.04761904762
}
},
{
“key” : 25,
“doc_count” : 42,
“ageAvg” : {
“value” : 27445.214285714286
}
},
{
“key” : 37,
“doc_count” : 42,
“ageAvg” : {
“value” : 27022.261904761905
}
},
{
“key” : 27,
“doc_count” : 39,
“ageAvg” : {
“value” : 21471.871794871793
}
},
{
“key” : 38,
“doc_count” : 39,
“ageAvg” : {
“value” : 26187.17948717949
}
},
{
“key” : 29,
“doc_count” : 35,
“ageAvg” : {
“value” : 29483.14285714286
}
}
]
}
}
}
复杂子聚合:
查出所有年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资
GET bank/_search
{
“query”: {
“match_all”: {}
},
“aggs”: {
“ageAgg”: {
“terms”: { # 看age分布
“field”: “age”,
“size”: 100
},
“aggs”: { # 子聚合
“genderAgg”: {
“terms”: { # 看gender分布
“field”: “gender.keyword” # 注意这里,文本字段应该用.keyword
},
“aggs”: { # 子聚合
“balanceAvg”: {
“avg”: { # 性别的平均薪资
“field”: “balance”
}
}
}
},
“ageBalanceAvg”: {
“avg”: { #age分布的平均(男女)
“field”: “balance”
}
}
}
}
},
“size”: 0
}
输出结果:
{
“took” : 119,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
最后
总而言之,面试官问来问去,问的那些Redis知识点也就这么多吧,复习的不够到位,知识点掌握不够熟练,所以面试才会卡壳。将这些Redis面试知识解析以及我整理的一些学习笔记分享出来给大家参考学习
还有更多学习笔记面试资料也分享如下:
聚合**
按照年龄聚合,并且求这些年龄段的这些人的平均薪资
写到一个聚合里是基于上个聚合进行子聚合。
下面求每个age分布的平均balance
GET bank/_search
{
“query”: {
“match_all”: {} #查询所有
},
“aggs”: {
“ageAgg”: {
“terms”: { # 看分布
“field”: “age”, #字段
“size”: 100 #数量
},
“aggs”: { # 与terms并列 【子聚合】
“ageAvg”: { #平均
“avg”: {
“field”: “balance”
}
}
}
}
},
“size”: 0
}
输出结果
{
“took” : 49,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
“hits” : {
“total” : {
“value” : 1000,
“relation” : “eq”
},
“max_score” : null,
“hits” : [ ]
},
“aggregations” : {
“ageAgg” : {
“doc_count_error_upper_bound” : 0,
“sum_other_doc_count” : 0,
“buckets” : [
{
“key” : 31,
“doc_count” : 61,
“ageAvg” : {
“value” : 28312.918032786885
}
},
{
“key” : 39,
“doc_count” : 60,
“ageAvg” : {
“value” : 25269.583333333332
}
},
{
“key” : 26,
“doc_count” : 59,
“ageAvg” : {
“value” : 23194.813559322032
}
},
{
“key” : 32,
“doc_count” : 52,
“ageAvg” : {
“value” : 23951.346153846152
}
},
{
“key” : 35,
“doc_count” : 52,
“ageAvg” : {
“value” : 22136.69230769231
}
},
{
“key” : 36,
“doc_count” : 52,
“ageAvg” : {
“value” : 22174.71153846154
}
},
{
“key” : 22,
“doc_count” : 51,
“ageAvg” : {
“value” : 24731.07843137255
}
},
{
“key” : 28,
“doc_count” : 51,
“ageAvg” : {
“value” : 28273.882352941175
}
},
{
“key” : 33,
“doc_count” : 50,
“ageAvg” : {
“value” : 25093.94
}
},
{
“key” : 34,
“doc_count” : 49,
“ageAvg” : {
“value” : 26809.95918367347
}
},
{
“key” : 30,
“doc_count” : 47,
“ageAvg” : {
“value” : 22841.106382978724
}
},
{
“key” : 21,
“doc_count” : 46,
“ageAvg” : {
“value” : 26981.434782608696
}
},
{
“key” : 40,
“doc_count” : 45,
“ageAvg” : {
“value” : 27183.17777777778
}
},
{
“key” : 20,
“doc_count” : 44,
“ageAvg” : {
“value” : 27741.227272727272
}
},
{
“key” : 23,
“doc_count” : 42,
“ageAvg” : {
“value” : 27314.214285714286
}
},
{
“key” : 24,
“doc_count” : 42,
“ageAvg” : {
“value” : 28519.04761904762
}
},
{
“key” : 25,
“doc_count” : 42,
“ageAvg” : {
“value” : 27445.214285714286
}
},
{
“key” : 37,
“doc_count” : 42,
“ageAvg” : {
“value” : 27022.261904761905
}
},
{
“key” : 27,
“doc_count” : 39,
“ageAvg” : {
“value” : 21471.871794871793
}
},
{
“key” : 38,
“doc_count” : 39,
“ageAvg” : {
“value” : 26187.17948717949
}
},
{
“key” : 29,
“doc_count” : 35,
“ageAvg” : {
“value” : 29483.14285714286
}
}
]
}
}
}
复杂子聚合:
查出所有年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资
GET bank/_search
{
“query”: {
“match_all”: {}
},
“aggs”: {
“ageAgg”: {
“terms”: { # 看age分布
“field”: “age”,
“size”: 100
},
“aggs”: { # 子聚合
“genderAgg”: {
“terms”: { # 看gender分布
“field”: “gender.keyword” # 注意这里,文本字段应该用.keyword
},
“aggs”: { # 子聚合
“balanceAvg”: {
“avg”: { # 性别的平均薪资
“field”: “balance”
}
}
}
},
“ageBalanceAvg”: {
“avg”: { #age分布的平均(男女)
“field”: “balance”
}
}
}
}
},
“size”: 0
}
输出结果:
{
“took” : 119,
“timed_out” : false,
“_shards” : {
“total” : 1,
“successful” : 1,
“skipped” : 0,
“failed” : 0
},
最后
总而言之,面试官问来问去,问的那些Redis知识点也就这么多吧,复习的不够到位,知识点掌握不够熟练,所以面试才会卡壳。将这些Redis面试知识解析以及我整理的一些学习笔记分享出来给大家参考学习
还有更多学习笔记面试资料也分享如下:
[外链图片转存中…(img-lucZd52Z-1719253093656)]