es查询

299 阅读7分钟

一.查询关键字

查询基本语法

 GET /{索引名}/_search
 {
     "from" : 0,  // 返回搜索结果的开始位置
     "size" : 10, // 分页大小,一次返回多少数据
     "_source" :[ ...需要返回的字段数组... ],
     "query" : { ...query子句... },
     "aggs" : { ..aggs子句..  },
     "sort" : { ..sort子句..  }
 }

1.terms、term查询

term query会去倒排索引中寻找确切的term,它并不知道分词器的存在,这种查询适合keyword、numeric、date等明确值的

 GET test_index1/_search
 {
   "query": {
     "term": {
       "name": "zhangsan"
     }
   }
 }
 ​
 GET test_index1/_search
 {
   "query": {
     "terms": {
       "name": ["zhangsan","lisi"]
     }
   }
 }

2.match查询

match query 知道分词器的存在,会对field进行分词操作,然后再查询

 GET test_index1/_search
 {
   "query": {
     "match": {
       "title":  "my ss",
       "analyzer": "ik_smart" //可以指定分词器  
     }
   }
 }

match和term区别可以理解为term是精确查询,这边match模糊查询;

  • 1.match会对my ss分词为两个单词
  • 2.term对认为这是一个单词

3.In匹配查询

 GET test_index1/_search
 {
     "query":{
         "terms":{
             "name":["张三","王五"]
         }
     }
 }

4.多条件查询语法

bool 过滤

bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:

  • must 多个查询条件的完全匹配,相当于 and。
  • must_not 多个查询条件的相反匹配,相当于 not。
  • should 至少有一个查询条件匹配, 相当于 or。

and查询 name=zhangsan,并且describe=xiangxixinxi

 GET test_index1/_search
 {
   "query": {
     "bool": {
       "must": [
         {
           "term": {
             "name": "zhangsan"
           }
         },
         {
           "term": {
             "describe": "xiangxixinxi"
           }
         }
       ]
     }
   }
 }

or查询 name=zhangsan,或describe=xiangxixinxi1

 GET test_index1/_search
 {
   "query": {
     "bool": {
       "should": [
         {
           "term": {
             "name": "zhangsan"
           }
         },
         {
           "term": {
             "describe": "xiangxixinxi1"
           }
         }
       ]
     }
   }
 }

5.boost权重查询

在Elasticsearch中,boost参数用于调整查询结果中每个文档的分数。分数越高,文档的相关性就越高,越有可能出现在搜索结果的前面。boost可以应用于不同的查询类型,包括matchtermbool等。

  1. 提升特定字段的权重:在match查询中,你可以为特定字段设置一个boost值,这样在搜索时,这个字段的匹配度会比其他字段更重要。
{
  "query": {
    "match": {
      "title": {
        "query": "双卡双待手机",
        "boost": 2.0
      }
    }
  }
}

在这个例子中,title字段的匹配度将比其他字段的匹配度高一倍。

  1. 提升特定查询的权重:在bool查询中,你可以为特定的子查询设置boost值,这样这个子查询的匹配度会比其他子查询更重要。
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": {
              "query": "双卡双待手机",
              "boost": 1.0
            }
          }
        }
      ],
      "should": [
        {
          "match": {
            "description": {
              "query": "双卡双待手机",
              "boost": 0.5
            }
          }
        }
      ]
    }
  }
}

在这个例子中,title字段的匹配度比description字段的匹配度高一倍。

boost的值可以是任何正数,通常在0到1之间,但也可以大于1。值越大,文档的分数就越高。需要注意的是,boost的使用应该谨慎,因为过高的boost值可能会导致搜索结果的相关性下降。

6.match_phrase查询

  • 可以搜索分词相邻的结果,eg 根据新疆苹果可以搜到香甜新疆苹果而搜不到新疆香甜苹果
  • 可以使用slop指定两个匹配的token位置距离的最大值。
  • 可以使用analyzer指定分词器,覆盖mapping中设置的search_analyzer

如下我们对"花花公子羽绒服"进行分词后发现,返回结果除了每个token之外,还拥有位置信息start_offsetend_offset。位置信息可以被保存在倒排索引(Inverted Index)中,像match_phrase这样位置感知(Position-aware)的查询能够使用位置信息来匹配那些含有正确单词出现顺序的文档,且在这些单词之间没有插入别的单词。

 GET idx_pro/_analyze
 {
   "text":"花花公子羽绒服",
   "analyzer" : "ik_smart"
 }
 {
   "tokens" : [
     {
       "token" : "花花公子",
       "start_offset" : 0,
       "end_offset" : 4,
       "type" : "CN_WORD",
       "position" : 0
     },
     {
       "token" : "羽绒服",
       "start_offset" : 4,
       "end_offset" : 7,
       "type" : "CN_WORD",
       "position" : 1
     }
   ]
 }

如下是我们的样本数据

 冬日工装裤 花花公子帅气外套 花花公子外套 冬天暖心羽绒服 冬日羽绒服 花花公子羽绒服 花花公子暖心羽绒服
 冬天超级暖心羽绒服

我们查询超级羽绒服搜索不到数据,因为没有超级羽绒服这样的短语存在。

 GET idx_pro/_search
 {
   "query": {
     "match_phrase": {
       "name": "超级羽绒服"
     }
   }
 }

搜索暖心羽绒服即可搜索到如下三个数据,因为暖心羽绒服被分词为羽绒服三部分,搜索到的结果必须符合他们三个分词的位置紧挨着。

 GET idx_pro/_search
 {
   "query": {
     "match_phrase": {
       "name": "暖心羽绒服"
     }
   }
 }
 冬天暖心羽绒服 冬天超级暖心羽绒服 花花公子暖心羽绒服

我们在设置了slop后允许超级羽绒服这两个分词后的token距离最大值为2,可以搜索到如下数据了。因为冬天超级暖心羽绒服分词结果为冬天超级,羽绒服超级羽绒服距离正好为2,所以能匹配到。

 CopyGET idx_pro/_search
 {
   "query": {
     "match_phrase": {
       "name": {
         "query": "超级羽绒服",
         "analyzer": "ik_smart",
         "slop": 2
       }
     }
   }
 }
 冬天超级暖心羽绒服

7.exists query

返回有name字段的文档,注意,如下情况将搜索不到文档:

  • 该字段的值为null或者是[],空字符串是可以搜索到的""
  • 该字段在mapping中设置了index:false
  • 该字段长度超出了mapping中的ignore_above的设置
  • The field value was malformed and ignore_malformed was defined in the mapping
 GET idx_pro/_search
 {
   "query": {
     "exists": {
       "field": "name"
     }
   }
 }

8.范围查询

Returns documents that contain terms within a provided range.

 GET user/_search
 {
     "query": {
         "range" : {
             "age" : {
                 "gte" : "2019-12-10",
                 "lte" : "2020-11-11",
                 "format" : "yyyy-MM-dd"
             }
         }
     }
 }
 ​
 GET user/_search
 {
     "query": {
         "range": {
             "birthday": {
                 "from": "1990-10-10",
                 "to": "2000-05-01",
                  "include_lower": true,
                 "include_upper": false
             }
         }
     }
 }

9.ids query

根据文档的_id返回文档

 CopyGET /_search
 {
     "query": {
         "ids" : {
             "values" : ["1", "4", "100"]
         }
     }
 }

10.过滤字段

查询全部字段

GET /lili_goods/_search
{
  "from" : 0,
  "size" : 10,
  "query": {
    "match":{
      "goodsName": "苹果"
    }
  }
}

查询指定字段

GET /lili_goods/_search
{
  "from" : 0,
  "size" : 10,
  "_source": [
      "goodsName",
      "sn"
    ], 
  "query": {
    "match":{
      "goodsName": "苹果"
    }
  }
}

包含和排除字段

 GET lib3/user/_search
 {
   "query":{
     "match_all": {}
   },
   "_source":{
      "includes": "addr*",
      "excludes": ["name","bir*"]
   }
 }

11.fuzzy实现模糊查询

fuzzy 查询是 term 查询的模糊等价。

 GET /lib3/user/_search
 {
     "query": {
         "fuzzy": {
              "interests": "chagge",
              "fuzziness": 2,  //允许出现错别字的个数
              "prefix_length": 1 //不允许搜索条件的第1字出错
         }
     }
 }

12.聚合查询

 GET lili_goods/_search
 {
   "query": {
     "match_all": {}
   },
   "aggs": {
     "brandIdAgg": {
       "terms": {
         "field": "brandId.keyword",
         "size": 10
       },
       "aggs": {
         "goodsIdAgg": {
           "terms": {
             "field": "goodsId.keyword",
             "size": 10
           }
         }
       }
       
     }
   }
 }
 GET attack_log/_search
 {
   "size":0,
   "query": {
     "bool": {
       "filter": [
         {
           "range": {
             "timestamp": {
               "gt": "1627747200000",
               "lt": "1629104108000"
             }
           }
         }
       ]
     }
   },
   "aggs": {
     "group_by": {
       "terms": {
         "field": "src_ip.keyword",
         "size":5,
         "order": {
           "_count": "desc"
         }
       }
     }
   }
 }
 GET /analysis/_search
 {
   "_source": {   ---SELECT
     "includes": ["fileName","starttime","duration","repNo","repGroup","typeOfService"],
     "excludes": ["blankKeyword","keyword","topicHitDetail"]
   }, 
   "query": {   ---WHERE
     "bool": {
       "filter": {
         "term": {
           "typeOfService": "转账"
         }
       }
     }
   },
   "aggs": {  ---GROUP BY
     "class_buckets": {  ---HAVING
       "filter": {
         "range": {
           "duration": {
             "gte": 600
           }
         }
       },
       "aggs": {
         "class_count": {
           "terms": {
             "field": "classfication_f"
           },
           "aggs": {
             "count": {
               "value_count": {
                 "field": "classfication_f"
               }
             },
             "count_filter":{
               "bucket_selector": { ------HAVING
                 "buckets_path": {
                   "count":"count"
                 },
                 "script": "params.count>=1000"
               }
             }
           }
         }
       }
     }
   },
   "from": 0, ---LIMIT
   "size": 10, 
   "sort": [    ---ORDER BY
     {
       "starttime": {
         "order": "desc"
       }
     }
   ]
 }

12.1 date_histogram的用法

 {
   "size": 0,
   "aggs": {
     "groupDate": {
       "date_histogram": {
         "field": "time",     # 查询字段
         "interval": "month", # 聚合时间间隔:year, quarter, month, week, day, hour, minute, second(年份、季度、月、周、日、小时、分钟、秒)
         "format": "yyyy-MM", # 格式化时间
         "time_zone":"+08:00" # 在es中日期支持时区的表示方法,这样就相当于东八区的时间
       }
     }
   }
 }

按月聚合查询数据

 GET /study/study_report/_search
 {
   "query": {
     "constant_score": {
       "filter": {
         "bool": {
           "must": [
             {
               "term": {
                 "course_subjects_name": "经济法基础"
               }
             },
             {
               "term": {
                 "user_id": 1939399
               }
             },
             {
               "range": {
                 "dt": {
                   "from": "20220801",
                   "include_lower": true,
                   "include_upper": true,
                   "to": "20220922"
                 }
               }
             }
           ]
         }
       }
     }
   },
   "size": 0,
   "aggs": {
     "sales_per_month": {
       "date_histogram": {
         "field": "time",
         "interval": "month",
         "format": "yyyyMM",
         "time_zone":"+08:00"
       },
       "aggs": {
         "sum_count_question": {
           "sum": {
             "field": "count_question"
           }
         },
         "sum_course_cat_id": {
           "sum": {
             "field": "course_cat_id"
           }
         }
       }
     }
   }
 }

13.高亮查询

 GET lili_goods/_search
 {
   "query": {
     "match": {
       "goodsName": "小米手机"
     }
   },
   "highlight": {
     "fields": {
       "goodsName": {}
     },
     "pre_tags": [
       "<span style=color:red>"
     ],
     "post_tags": [
       "</span>"
     ]
   }
 }

14.排序查询

 #排序查询:支持多字段排序
 GET hotel/_search
 {
   "query": {
     "match_all": {}
   },
   "sort": [
     {
       "price": {
         "order": "desc"
       }
     },
      {
       "salesVolume": {
         "order": "asc"
       }
     }
   ]
 }

15.通配符查询

当在搜索框进行搜索时,展示出所有品牌以美开头的酒店。

wildcardQuery:会对查询条件进行分词,还可以使用通配符 ?(任意单个字符) 和 * (0个或多个字符)

 GET hotel/_search
 {
   "query": {
     "wildcard": {
       "brand": {
         "value": "美*"
       }
     }
   }
 }