ElasticSearch查询
1. term&terms查询
1.1 term查询
term的查询是代表完全匹配,搜索之前不会对你索引的关键词进行分词,对你的关键字去文档分词库中去匹配内容。
PUT /sms-logs-index
{
"settings":{
"number_of_shards": 5,
"number_of_replicas":1
},
"mappings":{
"sms-logs-type":{
"properties":{
"createDate":{
"type":"date",
"format":"yyyy-MM-dd"
},
"sendDate":{
"type":"date",
"format":"yyyy-MM-dd"
},
"longCode":{
"type":"keyword"
},
"mobile":{
"type":"keyword"
},
"corpName":{
"type":"keyword"
},
"smsContent":{
"type":"text",
"analyzer": "ik_max_word"
},
"state":{
"type":"integer"
},
"operatorId":{
"type":"integer"
},
"province":{
"type":"keyword"
},
"ipAddr":{
"type":"ip"
},
"replyTotal":{
"type":"integer"
},
"fee":{
"type":"long"
}
}
}
}
}
1.2 terms查询
terms和term的查询机制是一样的,都不会将指定的查询关键词进行分词,直接去分词库中匹配,找到相应文档内容
terms是在针对一个字段包含多个值的时候使用,类似于IN
补充说明,分词和不分词的效果,
smsContent 通过ik分词器分词后
term&terms不会对进行分词所以查询不到
2. match查询
match查询属于高层查询,它会根据你的查询的字段类型不一样,采用不用的查询方式。
- 查询的是日期或者是数值的话,它会将你基于字符串查询内容转换为日期或者数值对待。
- 如果查询的内容是一个不能被分词的内容(keyword),match查询不会对你指定的查询关键字进行分词。
- 如果查询的内容时一个可以被分词的内容(text),match会将你指定的查询内容根据一定的方式去分词,去分词库中匹配指定的内容。
match查询,实际底层就是多个term查询,将多个term查询的结果给你封装到了一起。
2.1 match_all查询
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"match_all": {}
}
}
不加size默认返回10条数据
2.2 match查询
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"match": {
"smsContent": "河马订"
}
}
}
2.3 布尔match查询
基于一个Filed匹配的内容,采用and或者or的方式连续
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"match": {
"smsContent": {
"query": "河马 订单",
"operator": "and" #内容即包含河马也包含健康
}
}
}
}
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"match": {
"smsContent": {
"query": "河马 订单",
"operator": "or" #内容包含河马或者包含健康
}
}
}
}
3 _id查询
GET /sms-logs-index/sms-logs-type/5S6mU3gBe8iP1EnkCcIk
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"ids":{
"values": ["5S6mU3gBe8iP1EnkCcIk","5i6nU3gBe8iP1EnkpcJt"]
}
}
}
4. prefix查询
前缀查询
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"prefix": {
"corpName": {
"value": "河马"
}
}
}
}
5. fuzzy查询
模糊查询,我们输入字符的大概,ES就可以根据输入的内容大概去匹配一下结果。输入内容可以有错别字
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"fuzzy": {
"corpName": {
"value": "河马先生",
"prefix_length": 2
}
}
}
}
prefix_length 指定前面2个单词不能错
6. wildcard查询
通配符查询,和MySQL中的like是一个套路,可以在查询时,在字符串中指定通配符*和占位符?
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"wildcard": {
"corpName": {
"value": "河马*"
}
}
}
}
7. range查询
范围查询,只针对数值类型,对某一个Field进行大于或者小于的范围指定。
gt >
gte >=
lt <
lte <=
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"range": {
"fee": {
"gte": 2,
"lte": 5
}
}
}
}
8. regexp查询
正则查询,通过你编写的正则表达式去匹配内容
prefix,fuzzy,wildcard和regexp查询效率相对较低,要求效率比较高时,避免去使用。
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"regexp": {
"mobile": "186[0-9]{8}"
}
}
}
9. 深分页scroll
ES对from+size是有限制的,from和size二者之和不能超过1w
原理:
ES查询数据的方式,
第一步先将用户指定的关键字进行分词,
第二步将词汇去分词库中进行检索,得到多个文档的id,
第三步去各个分片中去拉取指定的数据。
第四步将数据根据score进行排序,
第五步根据from的值,将查询到的数据舍弃一部分,
第六步返回结果。
scroll在ES查询数据的方式:
第一步将用户指定的关键词进行分词。
第二步将词汇去分词库中进行检索,得到多个文档的id。
第三步将文档的id存放在一个ES的上下文中。
第四步根据你指定的size的格式去ES中检索指定的数据,拿完数据的文档id,会从上下文中移除。
第五步如果需要下一页数,直接去ES的上下文中,找后续内容。
scroll查询方式,不适合做实时的查询。
执行scroll查询,返回第一页数据,并且将文档id信息存放在ES上下文中,指定生存时间为1m
POST /sms-logs-index/sms-logs-type/_search?scroll=1m
{
"query": {
"match_all": {}
},
"size": 2,
"sort": [
{
"fee": {
"order": "desc"
}
}
]
}
根据第一次查询的结果的_scroll_id,查询下一页的数据,查询完的数据会从内存中删除
10. delete-by-query
根据term,match等查询方式去删除大量的文档
如果需要删除的内容是index下的大部分数据,推荐创建一个全新的index,将保留的文档内容,添加到全新的索引
POST /sms-logs-index/sms-logs-type/_delete_by_query
{
"query":{
"range":{
"fee":{
"lt": 5
}
}
}
}
11. 复合查询
11.1 bool查询
复合过滤器,将你的多个查询条件,以一定的逻辑组合在一起
- must: 所有的条件,用must组合在一起,表示And的意思
- must_not: 将must_not中的条件,全部都不能匹配,表示not的意思
- should: 所有的条件,用should组合在一起
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"province": {
"value": "北京"
}
}
},
{
"term": {
"province": {
"value": "武汉"
}
}
}
],
"must_not": [
{
"term": {
"operatorId": {
"value": "2"
}
}
}
],
"must": [
{
"match": {
"smsContent": "中国"
}
},
{
"match": {
"smsContent": "平安"
}
}
]
}
}
}
11.2 boosting查询
boosting查询可以帮助我们去影响查询后的score.
- positive: 只有匹配上positive的查询的内容,才会被放到返回的结果集中。
- negative: 如果匹配上的和positive并且也匹配上了negative,就可以降低这样的文档score.
- negative_boost:指定系数,必须小于1.0
查询是分数如何计算:- 搜索的关键字在文档中出现的频次越高,分数也就越高
- 指定的文档内容越短,分数就越高
- 我们在搜素时,指定的关键字也会被分词,这个分词的内容,被分词库匹配的个数越多,分数越高。
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"boosting": {
"positive": {
"match":{
"smsContent": "河马"
}
},
"negative":{
"match":{
"smsContent": "配送"
}
},
"negative_boost": 0.5
}
}
}
12 filter查询
query查询,根据你的查询条件,去计算文档的匹配度得到一个分数,并且根据分数进行排序,query不会做缓存
filter查询,根据你的查询条件去查询文档,不去计算分数,而且filter会对经常被过滤的数据进行缓存。
POST /sms-logs-index/sms-logs-type/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"corpName": "河马鲜生"
}
},
{
"range": {
"fee":{
"lt": 6
}
}
}
]
}
}
}
}