推荐 https://www.cnblogs.com/xfeiyun/p/15890024.html
查询一条
GET mr_zcy/_doc/82215
查询_id=82215 一条记录
查询所有数据
GET mr_zcy/_search
{
"query": {"match_all": {}}
}
或者
GET mr_zcy/_search
查询结果字段含义
返回结果说明:
- took字段表示该操作的耗时(单位为毫秒)。
- timed_out字段表示是否超时。
- hits字段表示搜到的记录,数组形式。
- total:返回记录数,本例是2条。
- max_score:最高的匹配程度,本例是1.0。
查询结果只返回部分属性
通过_source 字段来指定需要返回的字段。
将 _source 设置为 false, 可以不显示原始字段,部分特殊场景下会用到
显示 id和productName
POST product/_search
{
"_source": [
"id", "productName"
],
"query": {
"match_all": {}
}
}
POST mr_zcy/_search
{
"query": {"match_all": {}},
"_source":{
"includes": ["id", "productName"]
}
}
不显示source
GET mr_zcy/_search
{
"query": {"match_all": {}},
"_source": false
}
排除一些字段显示其他
POST mr_zcy/_search
{
"query": {"match_all": {}},
"_source":{
"excludes": ["Submitter"]
}
}
term查询
精确查询,不会对输入做分词,如果输入的是"某某人",则直接查询"某某人",如果输入的是"某某事",则直接查询"某某事"。
一般用于精确匹配 ,例如SELECT * FROM A表 where 字段=xxx
总结: 如果查询的字段类型是text, 那么是用term 是查询不到的. 对于字段类型keyword才有效
原因:
① 我想要进行查询的字段在创建mapping时使用的“text”数据类型进行创建。
② 众所周知text类型的数据在elasticsearch中会进行分词并建立倒排索引,因此它会对每个词进行索引,而不会建立整个句子的索引。
③ term搜索时会对整个句子作为关键词进行搜索,由于没有建立整个句子的关键词索引,因此无法查找到东西。
GET /xxx/_search
{
"query": {
"term": {
"normal_score": {
"value": 80
}
}
}
}
select * from xxx where normal_score=80
因为normal_score 是 long ,可以精确. 但是normal_score是text如何处理? 要转成keyword
如下id是text, 需要加keyword,否则term 查询不出来
GET /mr_zcy/_search
{
"query": {
"term": {
"id.keyword": "100185"
}
}
}
match查询
match搜索会先对搜索词进行分词,查询的字段类型是text,也会进行分词,其实这样查询结果不受控制了
我们知道match查询会对输入进行分词,我们可以指定对分词后的结果进行and和or查询。
and:代表分词后的所有结果都得匹配,or:代表分词后只要有一个结果匹配就行(默认是or)
GET /mr_zcy/_search
{
"query": {
"match": {
"systemAssignedTo": {
"query": "12020202",
"operator": "and"
}
}
}
}
select * from mr_zcy where systemAssignedTo like '%12020202%'
match_phrase短语查询
match_phrase为按短语搜索,比如根据一个文本搜索:“我的宝马多少马力”,这个文本可能会被分词成宝马、多少、马力三个短语,只有同时满足这三个才能被搜索出来。
----总结
和match一样,对搜索词会被分成多个词, 通过operate=and, 实现同时满足,和match_phrase效果一样
但是match_phrase 可以通过slop 因子, 可以少匹配也可以
GET /mr_zcy/_search
{
"query": {
"match_phrase": {
"systemAssignedTo": "涛1022234"
}
}
}
select * from mr_zcy where systemAssignedTo like '%涛1022234%'
完全匹配可能比较严,我们会希望有个可调节因子,少匹配一个也满足,那就需要使用到slop
---我不怎么用
GET /mr_zcy/_search
{
"query": {
"match_phrase": {
"systemAssignedTo":{
"query": "涛1022234",
"slop": 3
}
}
}
}
multi_match查询
多字段模糊查询,和match类似都是模糊查询,但multi_match可以指定多字段进行模糊查询。
一般用在select * from 表 where A like '%xx%' or B like '%xx%' or C like '%xx%'
我们希望完全匹配的文档占的评分比较高,则需要使用best_fields
我们会希望这个词条的分词词汇是分配到不同字段中的,那么就使用cross_fields
GET /mr_zcy/_search
{
"query": {
"multi_match":{
"query": "10022234",
"fields": ["systemAssignedTo","Submitter"],
"operator": "and",
"type": "best_fields"
}
}
}
我的场景一般是like 的场景
select * from mr_zcy where systemAssignedTo like '%10022234%' or Submitter like '%10022234%'
query_string查询
query_string和match类似,但是match需要指定字段名,query_string是在所有字段中搜索,范围更广泛(当然query_string也支持指定字段查询)。
GET /mr_zcy/_search
{
"query": {
"query_string": {
"query": "100122234",
"default_operator": "and"
}
}
}
---相当查询 mr_zcy 中所有字段执行 like '%100122234%'
GET /mr_zcy/_search
{
"query": {
"query_string": {
"fields": ["systemAssignedTo","requirementSubmitter","metricDealName"],
"query": "100122234",
"default_operator": "and"
}
}
}
---相当查询 mr_zcy 中 fields 里面的字段执行 like '%100122234%' 并且是or 关系
和mult_match 效果一样
类似mysql的like查询
除了match 使用oprtate=and 可以实现, 或者 match_phrase 也可以时间,再介绍一种 Wildcard
GET /mr_zcy/_search
{
"query": {
"wildcard": {
"systemAssignedTo.keyword": {
"value": "*1123445*"
}
}
}
GET /mr_zcy/_search
{
"query": {
"match_phrase": {
"systemAssignedTo":{
"query": "1123445",
}
}
}
}
两者区别
1> wildcard的 value 可以? 用来匹配一个任意字符,* 用来匹配零个或者多个字符。
2> wildcard的字段必须是keyworld类型
通过terms实现SQL的in语句
如果我们要实现SQL中的in语句,一个字段包含给定数组中的任意一个值就匹配。
注意是keyword
GET /mr_zcy/_search
{
"query": {
"terms": {
"systemAssignedTo.keyword": [
"朱100322345",
"王11110010297"
]
}
}
}
select * from mr_zcy where systemAssignedTo in ('朱100322345','王11110010297')
或通过bool实现
GET /mr_zcy/_search
{
"query": {
"bool": {"should": [
{"match": {
"systemAssignedTo":{
"query": "朱100322345",
"operator": "and"
}
}},
{"match": {
"systemAssignedTo":{
"query": "王11110010297",
"operator": "and"
}
}}
]}
}
范围查询range
通过range实现范围查询,类似SQL语句中的>, >=, <, <=表达式。
范围参数如下:
- gt - 大于 ( > )
- gte - 大于且等于 ( >= )
- lt - 小于 ( < )
- lte - 小于且等于 ( <= )
GET /zcy/_search
{
"query": {"range": {
"normal_score": {
"gte": 88,
"lte": 89
}
}}
}
select * from zcy where normal_score>=88 and normal_score<=89
时间范围
1> 字段是时间格式
"update_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
}
格式化的日期将使用指定的默认format(格式)解析date(日期)字段,但可以通过将格式参数传递到range (范围)查询来覆盖默认格式:
GET /project_zcy/_search
{
"query": {
"range": {
"update_time": {
"gte": "2022-12-08 03:22:40",
"lte": "2023", --支持"now" 表示当前时间
"format": "yyyy-MM-dd HH:mm:ss||yyyy"
}
}
},
"_source": "update_time",
"sort": [
{
"update_time": {
"order": "desc"
}
}
]
}
2> 字段类型不是时间,是text ,那边必须keyword
GET /project_xxx/_search
{
"query": {
"range": {
"update_time.keyword": {
"gte": "2022",
"lte": "2023"
}
}
},
"_source": "update_time",
"sort": [
{
"update_time.keyword": {
"order": "desc"
}
}
]
}
filter和match的区别
filter比较高效的原理
为了说明filter查询高效的原因,我们需要引入ES的一个概念 query context和 filter context。
query context关注的是,文档到底有多匹配查询的条件,这个匹配的程度是由相关性分数决定的,分数越高自然就越匹配。所以这种查询除了关注文档是否满足查询条件,还需要额外的计算相关性分数。
filter context关注的是,文档是否匹配查询条件,结果只有两个,是和否。没有其它额外的计算。它常用的一个场景就是过滤时间范围。并且filter context会自动被ES缓存结果,效率进一步提高。
对于bool查询,must使用的就是query context,而filter使用的就是filter context。
bool联合查询
通常我们可能需要将很多个条件组合在一起查出最后的结果,这个时候就需要使用ES提供的bool
来实现了
如果我们想要请求"productName中带宝马,但是brandName中不带宝马"这样类似的需求,就需要用到bool联合查询。
bool查询包括四种子句:
- must:文档必须完全匹配条件
- should:只要有一个或部分条件满足
- must_not:文档必须不匹配条件
- filter:返回的文档必须满足filter子句的条件。但是跟must不一样的是,不会计算分值, 并且可以使用缓存
GET /mr_zcy/_search
{
"query": {
"bool": {
"must": [ ---must 改成filter 效果一样.性能更快
{
"term": {
"warningState.keyword": "正常"
}
},
{
"bool": {
"should": [
{
"term": {
"systemAssignedTo.keyword": {
"value": "朱1123455"
}
}
},
{
"term": {
"id.keyword": {
"value": "154315"
}
}
}
]
}
}
]
}
}
}
regexp查询
GET books/_search
{
"query": {
"regexp": {
"postcode": "W[0-9].+"
}
}
}