ES(搜索 / 查询)

Posted xue_yun_xiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES(搜索 / 查询)相关的知识,希望对你有一定的参考价值。

一、数据准备

es 官方银行客户账户 数据 ,用来演示

1、下载数据

webget https://raw.githubusercontent.com/elastic/elasticsearch/master/docs/src/test/resources/accounts.json

2、将json 提交到es 中

curl -H “Content-Type: application/json” -XPOST “192.168.12.130:9200/bank/_doc/_bulk?pretty&refresh” --data-binary “@accounts.json”

3、查看bank 结构

根据id查询
GET /bank/_doc/1
搜索
GET /bank/_search
查看 _doc 结构
GET /bank/

说明


“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” #国家简称

二、搜索

1、term&terms查询

term terms 搜索 是按照关键字搜索,查询的属性必须是关键字 (keyword)

#term 只匹配 keyword
POST /bank/_doc/_search

  "from": 0,    
  "size": 5,
  "query": 
    "term": 
      "state.keyword": 
        "value": "DE"
      
    
  


# terms查询
#  只要查询的 属性值 符合其中一个 就查询出来
POST /bank/_doc/_search

  "from": 0,
  "size": 20
  , 
  "query": 
    "terms": 
      "state.keyword": [
        "DE",
        "PA"
      ]
    
  
  

2、match查询【重点

match查询属于高层查询,他会根据你查询的字段类型不一样,采用不同的查询方式。

  • 查询的是日期或者是数值的话,他会将你基于的字符串查询内容转换为日期或者数值对待。
  • 如果查询的内容是一个不能被分词的内容(keyword),match查询不会对你指定的查询关键字进行分词。
  • 如果查询的内容时一个可以被分词的内容(text),match会将你指定的查询内容根据一定的方式去分词,去分词库中匹配指定的内容。

match查询,实际底层就是多个term查询,将多个term查询的结果给你封装到了一起。

查询所有

# 查询所有
POST /bank/_doc/_search

    "from": 0,
  "size": 5,
  "query": 
    "match_all": 
  


# 查询所有
POST /bank/_doc/_search

    "from": 0,
  "size": 5

根据单词查询

# address  是 text 类型
# match 时 会将 要查询的数据进行切分,查询出来 只要任意一个文档含有其中一个 单词 ,就查出来
POST /bank/_doc/_search

  "from":0,
  "size":20,
  "query":
    "match":
      "address":"Avenue Baycliff Place"
    
  

match 多条件查询
or 或者 and 匹配多个单词

#或者关系
POST /bank/_doc/_search

  "from":0,
  "size":20,
  "query":
    "match":
      "address":
        "query":"Avenue Newkirk",
        "operator":"and"
      
     
    
  

多条件multi_match查询

match针对一个field做检索,multi_match针对多个field进行检索,多个field对应一个text。

# 两个字段含有一个符合条件就可以
# 我们查询 两个属性 只要有一个属性匹配查询单词 ,就查出来
POST /bank/_doc/_search

  "from":0,
  "size":20,
  "query":
     "multi_match": 
      "query": "Hondah  Avenue",				
      "fields": ["city","address"]    
    
  

3、根据id 查询

GET /bank/_doc/1

# 根据id  一次查询多个
POST /bank/_doc/_search

  "query":
    "ids":
      "values":["1","2","3"]
    
  


4、wildcard查询 卡方查询

通配查询,和mysql中的like是一个套路,可以在查询时,在字符串中指定通配符*和占位符?

5、range查询

范围查询,只针对数值类型,对某一个Field进行大于或者小于的范围指定
gt:> 大于
gte:>= 大于等于
lt:< 小于
lte:<= 小于等于

# 使用 range  查询属性 是数值型的 范围
POST /bank/_doc/_search

   "from":0,
   "size":20,
  "query": 
    "range": 
      "age": 
        "gt": 24,
        "lte": 25
       
      
    
  

6、复合查询

复合查询就是将 上面学习的 term terms match multi_match 等 组合起来 通过 should(只要满足一个就可以) must(所有都必须满足) must_not( 所有的有应该 不满足)

bool查询

复合过滤器,将你的多个查询条件,以一定的逻辑组合在一起

  • must: 所有的条件,用must组合在一起,表示And的意思
  • must_not:将must_not中的条件,全部都不能匹配,标识Not的意思
  • should:所有的条件,用should组合在一起,表示Or的意思
# 如果 should 和 must 一起使用  should 默认不起作用

POST /bank/_doc/_search

  "query": 
    "bool": 
      "should": [  
        
          "term": 
            "city.keyword": 
              "value": "Mathews"
            
          
        ,
        
          "term": 
            "city.keyword": 
              "value": "Shaft"
            
          
        
      ],
      "must_not": [
        
          "term": 
            "age": 
              "value": "39"
            
          
        
      ],
      "must": [
        
          "match": 
            "state": "DE"
          
        ,
        
          "match": 
            "lastname": "Bartlett"
          
        
      ],
     "minimum_should_match": 1
    
  

补充

# 模糊查询 将descr 当成关键字 作为整体 去模糊匹配 *名著*

POST /book2/novel/_search

   "from":0,
   "size":5,
    "query":
       "wildcard":
         "descr.keyword":
           "value":"*名著*"
         
       
    

GET /book2

没有分词器
"descr" : 
            "type" : "text",
            "fields" : 
              "keyword" : 
                "type" : "keyword",
                "ignore_above" : 256
              
            
          
          
为什么    book2  中的 descr 不能模糊?
就是因为没有为descr 配置分词器,将descr对应的值 切分为每一个字 ,现在去模糊匹配 "*名著*"
          

POST /book/novel/_search

   "from":0,
   "size":5,
    "query":
       "wildcard":
         "descr.keyword":
           "value":"*名著*"
         
       
    

GET /book       有分词器,可以将 descr进行分词

 "descr" : 
            "type" : "text",
            "analyzer" : "ik_max_word"
          ,
因为    /book        descr 有分词器,在加入数据时会自动将descr 进行切分 切分为单词,所以
/book 模糊匹配单词  "*名著*"
          

7、filter查询

query:根据你的查询条件,去计算文档的匹配度得到一个分数,并且根据分数进行排序,不会做缓存的。
filter:根据你的查询条件去查询文档,不去计算分数,而且filter会对经常被过滤的数据进行缓存。

如果在查询时仅仅是为了查询出来,不要查询结果的准确性,我们一般都使用filter ,因为没有评分,不需要排序,性能更好


# 过滤
POST /bank/_doc/_search

  "query": 
    "bool": 
      "filter": [
        
          "term": 
            "address": "731"
          
        ,
        
          "range": 
            "age": 
              "lte": 40
            
          
        
      ]
    
  

8、 高亮显示

POST /bank/_doc/_search

  "query": 
    "match": 
      "address": "Street"
    
  ,
  "highlight": 
    "fields": 
      "address": 
    ,
    "pre_tags": "<font color='red'>",  #前缀
    "post_tags": "</font>",     #后缀
    "fragment_size": 10
  


9、聚合查询

就是将 结果按照一定的 属性 对应 的规则 进行分组,分组内 求平均值 最大值 最小值 ,数量

去重计数查询

去重计数,即Cardinality,第一步先将返回的文档中的一个指定的field进行去重,统计一共有多少条
field 对应的列必须是关键字,如果不是需要province.keyword

POST /bank/_doc/_search

  "aggs":   #聚合
    "agg":    
      "cardinality":  # 去重
        "field": "state.keyword" #按照 state 去重,去重时属性必须是 keyword
      
    
  
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210629212607643.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h1ZV95dW5feGlhbmc=,size_16,color_FFFFFF,t_70)

范围统计

统计一定范围内出现的文档个数,比如,针对某一个Field的值在 0100,100200,200~300之间文档出现的个数分别是多少。

范围统计可以针对普通的数值,针对时间类型,针对ip类型都可以做相应的统计。
range,date_range,ip_range

数值统计

POST /bank/_doc/_search

  "aggs": 
    "agg": 
      "range": 
        "field": "age",
        "ranges": [
          
            "to": 15
          ,
          
            "from": 15,  
            "to": 30
          ,
          
            "from": 30
          
        ]
      
    
  

对数值型 属性进行统计


#平均年龄

POST /bank/_doc/_search

  "aggs": 
    "agg": 
      "extended_stats": 
        "field": "age"
      
    
  

以上是关于ES(搜索 / 查询)的主要内容,如果未能解决你的问题,请参考以下文章

ES(搜索 / 查询)

ES(搜索 / 查询)

es深入搜索之全文检索

ES 搜索引擎

记录es的URI search搜索方式

es的scoll滚动查询技术