elasticsearch-各种查询

本文查询基于es6.4.3版本,其他版本可能会有差异,有就再说吧…
7.x以上有个大坑,有些字段查不出来的话,加上 .keyword试…例如这样:

"term": {
     "xxxid.keyword": "sdfsdf"
 }

文章目录

    • 特别注意
    • 基本语法
      • 返回值说明
      • 指定想要显示的字段和不想要显示的字段
      • 进行脚本排序
      • es7.x在查询时,必须加上track_total_hits,不然就只显示10000
      • term查询:
      • terms查询:
      • match_all查询:
      • match : 分词匹配查询
      • 布尔match : 分词匹配查询
      • multi_match: 多字段查询,就是查询符合的多个字段
      • match_phrase
      • ids: 多id查询
      • prefix:前缀查询,就是搜索的时候,你输入关键字,然后去搜索这个关键字开头的值
      • fuzzy: 模糊查询
      • wildcard: 通配符查询
      • range查询
      • range, match, from, size组合查询
      • match和should配合使用
      • must包含should配合使用
      • regexp查询
      • scroll深分页
      • delete-by-query
      • 存在与否检索 exist
      • bool查询
      • boosting查询
      • filter过滤查询
      • 高亮查询
      • 聚合cardinality查询
      • 聚合range查询
      • 聚合extended_stats查询

特别注意

  • es的查询时候,如果不指定from和size,默认size是10,坑啊…
  • es查询当数量超过10000的时候需要加上 “track_total_hits”: true, 类似这样:
  • preference=“_primary_first” : 设置为主分片, 有时候查询会在各个分片之间切换,导致查询总数不一致
GET /table/_search?preference="_primary_first"
{
	"track_total_hits": true, 
	......
}
  • 查询es各个节点情况:GET /_cat/allocation?v

基本语法

GET /索引/_search
{
	"query":{
        "查询类型":{
            "查询条件":"查询条件值"
        }
    }
}

这里的query代表一个查询对象,里面可以有不同的查询属性;
属性有:
- term : 精准查询
- terms : 精准查询多条
- match_all : 查询所有
- match : 分词匹配查询
- 布尔match : 分词匹配查询
- multi_match: 多字段查询,就是查询符合的多个字段
- ids: 通过多个id来查询
- prefix:前缀查询,就是搜索的时候,你输入关键字,然后去搜索这个关键字开头的值
- fuzzy: 模糊查询
不同属性之间写法有差异,下面有仔细说明;


返回值说明

  • took:查询花费时间,单位是毫秒
  • time_out:是否超时
  • _shards:分片信息
  • hits:搜索结果总览对象
    • total:搜索到的总条数
    • max_score:所有结果中文档得分的最高分
    • hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
      • _index:索引库
      • _type:文档类型
      • _id:文档id
      • _score:文档得分
      • _source:文档的源数据

指定想要显示的字段和不想要显示的字段

  • includes:来指定想要显示的字段, 例如:
只显示 EnterpriseName, ProductName, ProductModel 三个字段
GET /index/_search
{
  "_source": {
    "includes": ["EnterpriseName","ProductName","ProductModel"]
  },
  "query": {
    "multi_match": {
      "query": "偷百大理同志",
      "fields":["EnterpriseName","ProductName","ProductModel"]
    }
  }
}
  • excludes:来指定不想要显示的字段
不显示 EnterpriseName, ProductName, ProductModel 三个字段
GET /index/_search
{
 "_source": {
   "excludes": ["EnterpriseName","ProductName","ProductModel"]
 },
 "query": {
   "multi_match": {
     "query": "偷百大理同志",
     "fields":["EnterpriseName","ProductName","ProductModel"]
   }
 }
}

进行脚本排序

GET /t_hco_hcp/_search
{
  "from" : 0,
  "size" : 20,
  "track_total_hits": true, 
  "sort": {
    "_script": {
      "type": "number",
      "script": {
        "source": "(doc['hcp_name.keyword'].value.length()>0?1:0) +
        (doc['hcp_standard_dept_name.keyword'].value.length()>0?1:0) + 
        (doc['hco_name.keyword'].value.length()>0?1:0) + 
        (doc['hcp_nhc_location.keyword'].value.length()>0?1:0) + 
        (doc['hcp_professional_title.keyword'].value.length()>0?1:0) + 
        (doc['hcp_academic_title.keyword'].value.length()>0?1:0)"
      },
      "order": "desc"
    },
    "_score" :{
      "order": "desc"
    }
  },
  "query": 
  {
    "bool": {
    	
  }
}

es7.x在查询时,必须加上track_total_hits,不然就只显示10000

例如这样:

GET /index_name/_search
{
  "track_total_hits": true, 
  "query": 
  {
  	"bool": {
  		"must": [
  		  {
    			"term": 
    			{
    				"xxxxx.keyword": "xxxx"
    			}
    		}
  		]
  	}
  }
}

term查询:

完全精准匹配,不会对关键字进行分词,需要一摸一样才能查出来;
注意:这里的字段值可能是数字、时间、布尔或者那些 未分词的字符串

POST /索引/类型/_search
{
	"from" : 0,
	"size" : 5,
	"query" : {
		"term": {
			"字段名称" : 字段值  
		}
	}
}

查不到加 .keyword
查不到加 .keyword
查不到加 .keyword


terms查询:

也是完全匹配,查询方式和term一样,只不过这里是多值查询。
term的意思是 value=xxx;
terms的意思是 value = aaa 或者 value = bbb 或者 value = cccc;

POST /索引/类型/_search
{
	"from" : 0,
	"size" : 5,
	"query" : {
		"terms": {
			"字段名称": [字段值,字段值,字段值]
		}
	}
}

match_all查询:

查询所有,就是字面意思

POST /索引/类型/_search
{
	"query" : {
		"match_all": {}
	}
}

match : 分词匹配查询

  • 如果查询的是日期或者数值,会将你基于的字符串查询内容转换为日期或者数值;
  • 查询的字段是 keyword 类型,则不会进行分词匹配;
  • 查询的字段是 text 类型,则会进行分词匹配;
  • 啥是分词匹配:
    如果想查询值为 “英国大理石” 的字段,输入的参数只要匹配其中的任意一个字即可查询到;
POST /索引/类型/_search
{
  "query": {
    "match": {
      "字段名称":"大头"		// 大  字匹配到了 "英国大理石",  所以能查询到 ”英国大理石这个数据“
    }
  }
}

布尔match : 分词匹配查询

  • 与match查询规则一样,只是这里多了条件判断;
  • 语法变了一点,operator 参数:
    or : 或的关系,表示query里面的词只要满足一个字就可以匹配到;
    and : 并且的关系,表示query里面的词(分词)都要满足才可以匹配到;
POST /索引/类型/_search
{
  "query": {
    "match": {
      "字段名称":{
        "query": "英国大理",
        "operator": "or"
      }	
    }
  }
}

multi_match: 多字段查询,就是查询符合的多个字段

多字段匹配,只要表里面有一个字段符合,就能查询到。

POST /索引/类型/_search
{
  "query": {
    "multi_match": {
      "query": "大理同志",
      "字段名称数组":["Name","Model","Address"]
    }
  }
}

match_phrase

与 match 查询类似,只是使用match_phrase 是进行词的完全匹配,字段有一个字不对应都不行
例如 想要匹配的词是 “大风吹着谁”
输入关键词 “大风”, match 和 match_phrase 都能查得到。
输入关键词 “大海”,match 能匹配得到,match_phrase 匹配不到。


ids: 多id查询

POST /索引/类型/_search
{
  "query": {
    "ids": {
    	"value" : ["id1", "id2", "id3"]
    }
  }
}

prefix:前缀查询,就是搜索的时候,你输入关键字,然后去搜索这个关键字开头的值

类似数据关键字 “深圳”, 引擎就会去搜索以 “深圳” 开头的数据, 注意,keyword类型的字段也能进行前缀查询。

POST /索引/类型/_search
{
  "query": {
    "prefix": {
      "字段名称": {
        "value": "深圳"
      }
    }
  }
}

fuzzy: 模糊查询

从5.0.0开始已经标记为过时。
将在6.0中正式移除,使用匹配查询替代模糊查询。
特此说明一下,如果要用模糊查询的话,中文就直接用match来查,英文的话可以用 wildcard 通配符查询和 regexp 正则表达式查询,这两个兄弟在后面讲。

wildcard: 通配符查询

wildcard可以进行通配符查询,允许使用通配符*和?来进行查询:
*代表任意个字符, ?代表一个字符
例如:

查询xxx的数据,条件是xxx的值里面包含 zh 这两连着的个字符,zh前面和后面可以有任意个其他字符;
?依次类推,就是zh前面和后面可以有1个其他字符;
GET /index/_doc/_search 
{
  "query": {
    "wildcard":{ 
    	"xxx":"*zh*"
    }
  }
}

GET /index/_doc/_search 
{
  "query": {
    "wildcard":{ 
    	"xxx":"?zh?"
    }
  }
}

range查询

范围查询,只针对数值类型,对于字符串无效;
gte : 大于等于
gt : 大于
lte : 小于等于
lt : 小于

查询字段值在 0 - 100 之间的数据
GET /index/_doc/_search 
{
  "query": {
    "range":{ 
    	"字段名称": {
			"gte" : 0,		  大于等于这个
			"lte" : 100				小于等于这个
		}
    }
  }
}

range, match, from, size组合查询

{
	"from":0,		//从第一条开始
    "size":2,		//查2条
    "query": {  
        "bool":{
        	// 这里must是一个查询条件数组,数组中每个元素都必须满足才可以
            "must":[
                {
                    "match": {
                        "decryptMsg":"测试"	
                    }
                },
                {
                    "range":{
                        "msgtime":{
                            "gte":1616032237310,
                            "lte":1616032237555
                        }
                    }
                }
            ]
        }
    }
}

match和should配合使用

{
	"from":0,
    "size":3,
    "query": {
        "bool":{
            "must":{
                "match":{
                    "decryptMsg":{
                        "query":"测试"
                    }
                }
            },
            "should":[
                {
                    "term":{
                        "xxId":"hhhh"
                    }
                },
                {
                    "term":{
                        "xxId":"hhhhh"
                    }
                }
            ]
        }
    }
}

must包含should配合使用

{
    "from": 0,
    "size": 15,
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "decryptMsg": "管理"
                    }
                },
                {
                    "bool":{
                        "should": [
                            {
                                "term": {
                                    "sendfrom.keyword": "rickey"
                                }
                            },
                            {
                                "term": {
                                    "tolist.keyword": "rickey"
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}

regexp查询

正则查询,通过正则表达式去查询。
ps : prefix, wildcard和regexp都属于可以匹配正则的查询,效率比较低, 要求效率高时候,尽量不要用这些查询。

GET /index/_doc/_search 
{
  "query": {
    "regexp": {
      "字段值": "160[0-9]{7}"		//查询以160开头,剩下的是0-9之间的,剩余有7位,的数据
    }
  }
}

scroll深分页

es对from+size查分页是有限制的,from和size之间不能查询超过10000条的数据,超过的话查询非常慢。
原因
from+size在es查询数据的过程:

  • 先把用户指定的关键字去分词;
  • 去检索,得到多个文档的id;
  • 拿到id去各个分片中拉取数据; 耗时较长
  • 根据得分score进行排序; 耗时较长
  • 如果有from和size,会根据size进行数据舍弃;
  • 返回结果;

scroll在es中查询数据的过程:

  • 先把用户指定的关键字去分词;
  • 去检索,得到多个文档的id;
  • 把文档id放入es的上下文中,相当于es的内存中;
  • 根据指定的size去es中检索指定的数据,取完之后的id,会从上下文(内存)中移除;
  • 需要下一页数据的话,直接去es上下文中找接下来的id数据,因为查过的id已经从上下文中移除了;
  • 默认根据id排序,但是可以手动指定排序方式;

例如:

  • from:3000,size:3100的话需要从0找到3100条数据,然后丢弃前面3000条,只要3000-3100之间的数据, 实际上查询和排序了3100条数据
  • 使用scroll的话,是从上下文中找到最后一百条数据的id,然后去查询,实际上就是查询和排序了100条数据。

优点:效率高;
缺点:scroll不适合支持那种实时的和用户交互的前端分页工作(因为有时候结果id会有变动,但是scroll是一次查出所有id放入上下文,查询的数据不是最新的)。
其主要用途用于从ES集群分批拉取大量结果集的情况,一般都是offline的应用场景。
比如需要将非常大的结果集拉取出来,存放到其他系统处理,或者需要做大索引的reindex等等;

//使用scroll查询,查询出来的结构在上下文中存在1分钟,然后删除
GET /index/_doc/_search?scroll=1m
{
  "query": {
    "match_all": {}
  },
  "size" : 3,		//查询3条, 之后使用这次查出来的scroll_id进行的查询,都是查这个条数
  "sort" : [
		{
			"MinPrice" : {
				"order" : "desc" 	//指定排序方式为 MinPrice 字段从大到小降序排序
			}
		}
	]
}

查询出来的数据:

  • _scroll_id : 存放在上下文中的文档id

进行下一页查询

//不能指定索引和doc
GET /_search/scroll	
{
	"scroll_id " : "xxxxxxxxxxx",
	"scroll" : "1m"		//再次指定查询scroll之后保存上下文的时间,如果不指定的话,这个上下文就直接销毁
}

删除scroll在内存中的上下文
DELETE /_search/scroll/scroll_id


delete-by-query

根据查询条件去删除大量文档数据
ps : 如果要删除大量的数据的话,不建议使用这种方式,因为这种方式实际上也是一条一条的去删。
推荐创建一个全新的索引,把要保留的数据放入新的索引。

//删除查询出来的数据
POST /index/_doc/_delete_by_query
{
  "query": {
    "range":{ 
    	"字段名称": {
			"gte" : 0,		  大于等于这个
			"lte" : 100				小于等于这个
		}
    }
  }
}

存在与否检索 exist

检测是否存在该字段.

name 这个字段必须存在

{
  "query": {
    "bool": {
      "must": {
        "exists": {
          "field": "name"
        }
      }
    }
  }
}

类似 mysql 的 :select * from xxxx where name is not null


bool查询

bool过滤器组成部分:

{
   "bool" : {
      "must" :     [],
      "should" :   [],
      "must_not" : [],
      "filter":    []
   }
}
  • must 所有的语句都 必须(must) 匹配,类似 mysql 的 AND
  • must_not 所有的语句都 不能(must not) 匹配, 类似 mysql 的 NOT
  • should 至少有一个语句要匹配,与 OR 等价
  • filter 必须匹配,运行在非评分&过滤模式

boosting查询

TODO

filter过滤查询

TODO

高亮查询

TODO

聚合cardinality查询

TODO

聚合range查询

TODO

聚合extended_stats查询

TODO

你可能感兴趣的:(elasticsearch,数据库,后端)