天天看點

Elasticsearch筆記-es基礎版——一看就會

文章目錄

          • 1、基礎
          • 2、文法
          • 3、基本查詢
          • 4、進階查詢
1、基礎
  1. elasticsearch是一個分布式的全文搜尋引擎。
    基于Lucene。具有restful的api接口。分布式,高橫向擴充能力。
    全文檢索:分詞,在分詞庫想分詞後的關鍵詞。反向索引。
               
  2. 與solr的差別
    效率:
    單純的對已有資料進行檢索的時候,solr效率更好,高于es;在不斷動态添加資料的時候,solr的檢索效率會變的低下,而es則沒有什麼變化。
    獨立性:
    Solr利用zookeeper進行分布式管理,而es自身帶有分布式系統管理功能。
               
  3. 反向索引也叫反向索引,通俗來講正向索引是通過key找value,反向索引則是通過value找key。
  4. type在7中已經被遺棄,ES官方建議 在一個索引庫中隻存儲相同類型的文檔。
  5. ik分詞器

    可以去GitHub下載下傳,但是網絡問題,可以進入容器,然後切到目錄 /usr/share/elasticsearch/bin。之後可以執行./elasticsearch-plugin install http://tomcat01.qfjava.cn:81/elasticsearch-analysis-ik-6.5.4.zip。最後重新開機一下。

    POST _analyze
    {
      "analyzer": "ik_max_word",
      "text": "中國湖北"
    }
    # 分為了[中國]和[湖北]
               
2、文法
  1. field字段類型,常見如下
    字元串類型
    text 、 keyword
    數值類型
    long, integer, short, byte, double, float, half_float, scaled_float
    日期類型
    date
    布爾值類型
    boolean
    二進制類型
    binary
    範圍類型
    integer_range, float_range, long_range, double_range, date_range
               
  2. 操作es的restful文法。原本的put修改,post新增,get查詢,delete删除

    Get:查詢

    # 查詢索引資訊
    http://ip:port/index
    # 查詢文檔資訊
    http://ip:port/index/type/doc_id
               
    Post:查詢
    # 查詢(查詢參數太多的情況,參數可以json格式傳參)
    http://ip:port/index/type/_search
    # 更新
    http://ip:port/index/type/doc_id/_update
    
    #建立一個文檔(一條資料)
    http://ip:port/index/type/doc
               
    Put:建立索引
    # 建立一個索引,請求體中指定資料結構(即type和字段,settings和mappings)
    http://ip:port/index
    
    # 建立一個文檔的屬性有哪些,請求體中指定具體資訊
    http://ip:port/index/type/_mappings
    
    #建立一個文檔(一條資料)
    http://ip:port/index/type/doc
               
    Delete:删
    # 删除一個索引,對應的資料全部被删除了
    http://ip:port/index
    # 删除一個文檔
    http://ip:port/index/type/doc_id
               
  3. 具體操作

    3.1 索引操作

    建立一個索引

    # 簡單建立一個索引,預設副本數為1,分片數為5
    PUT /qsm
    # 簡單建立一個索引,指定副本數和分片數
    PUT /qsm1
    {
      "settings": {
        "number_of_shards": 5
        , "number_of_replicas": 1
      }
    }
    # 若已建立索引,給索引添加資料結構
    PUT /qsm/novel/_mappings
    {
      "properties":{
            "name":{
              "type":"text"
            },
            "author":{
              "type":"keyword"
            },
            "count":{
              "type":"long"
            },
            "onSale":{
              "type":"date",
              "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
            }
          }
    }
    
    # 建立一個索引并制定資料結構
    PUT /book
    {
      "settings": {
        "number_of_shards": 5
        , "number_of_replicas": 1
      },
      "mappings": {
        "novel":{
          "properties":{
            "name":{
              "type":"text",
              "analyzer":"ik_max_word"
            },
            "author":{
              "type":"keyword"
            },
            "count":{
              "type":"long"
            },
            "onSale":{
              "type":"date",
              "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
            }
          }
        }
      }
    }
               
    删除索引
    # 删除某一個索引
    DELETE /qsm
    # 删除某個字首的所有索引
    DELETE /qsm*
               
    檢視索引資訊
    # 檢視某個索引
    GET /qsm1
    # 檢視所有索引清單
    GET /_cat/indices?v
               

    3.2 文檔操作

    建立文檔

    # 自動建立文檔id
    POST /book/novel
    {
      "name":"大秦帝國",
      "author":"qsm",
      "count":"10",
      "onSale":"2020-07-21"
    }
    # 手動建立文檔id
    POST /book/novel/1
    {
      "name":"大清帝國",
      "author":"qsm",
      "count":"20",
      "onSale":"2020-07-11"
    }
               
    更改文檔
    # 覆寫修改,直接相當于已知文檔id的手動建立
    POST /book/novel/1
    {
      "name":"大清帝國_copy",
      "author":"qsm",
      "onSale":"2020-07-11"
    }
    # 制定修改,基于doc
    POST /book/novel/1/_update
    {
      "doc": {
        "name":"大清帝國_copy2"
      }
    }
               
    删除文檔
    DELETE /book/novel/qk4vcHMBO6OsUd5sLTc
               
    查詢文檔
    GET /book/novel/1
               
  4. 深分頁

    ES對from和size之和有限制,不能大于1w

    from+size原理:

    根據使用者輸入的詞語進行分詞

    将分詞後的分詞去分詞庫中進行檢索,得到文檔的id

    去各個分片中拉去指定的資料

    根據資料的score分數進行排序

    根據from/limit進行篩選出指定的資料,其他資料舍棄

    傳回結果

    scroll+size原理:

    根據使用者輸入的詞語進行分詞

    将分詞後的分詞去分詞庫中進行檢索,得到文檔的id

    将文檔的id【放入到一個es上下文中】

    根據指定的size去各個分片中拉去指定的資料,并且拿完的文檔id會被上下文移除

    若需要下一頁size的資料,則去es上下文中拿到文檔id

    接下來跟第四步一樣,進行循環

    是以scroll沒有分數,且不适合實時查詢。但是非常快,資源消耗少。

    指定scroll查詢的時候,會給這個上下文指定過期時間(可以保持)。排序預設是id,也可以手動自定

    # from+size
    POST /sms-logs-index/sms-logs-type/_search
    {
      "from": 0,
      "size": 2, 
      "query": {
        "wildcard": {
          "smsContent": {
            "value": "*荊楚"
          }
        }
      }
    }
    # 指定scroll查詢
    POST /sms-logs-index/sms-logs-type/_search?scroll=2m
    {
      "size": 2 ,
      "query": {
        "match": {
          "smsContent": "荊楚"
        }
      },
      "sort": [
        {
          "fee": {
            "order": "desc"
          }
        }
      ]
    }
    #得到資料中"_scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAA0yFndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANMxZ3REZpa01EYlJONjVZYXUtbExJak5RAAAAAAAADTQWd0RGaWtNRGJSTjY1WWF1LWxMSWpOUQAAAAAAAA02FndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANNRZ3REZpa01EYlJONjVZYXUtbExJak5R"
    
    # scroll下一頁查詢
    POST /_search/scroll
    {
      "scroll_id":"DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAA0yFndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANMxZ3REZpa01EYlJONjVZYXUtbExJak5RAAAAAAAADTQWd0RGaWtNRGJSTjY1WWF1LWxMSWpOUQAAAAAAAA02FndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAANNRZ3REZpa01EYlJONjVZYXUtbExJak5R",
      "scroll":"2m"
    }
    
    # 删除scroll
    DELETE /_search/scroll/DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAA4_FndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAAOQRZ3REZpa01EYlJONjVZYXUtbExJak5RAAAAAAAADkAWd0RGaWtNRGJSTjY1WWF1LWxMSWpOUQAAAAAAAA5CFndERmlrTURiUk42NVlhdS1sTElqTlEAAAAAAAAOQxZ3REZpa01EYlJONjVZYXUtbExJak5R
               
3、基本查詢

查詢的基本知識:

若想查詢短信資訊字段中包含“中國湖北”的資料。則ik分詞器會"中國湖北"分為“中國湖北”,“中國”,“湖北”,那麼有這三個字段的文檔都會比對查詢到,但是會有一個分數,分數最高則會最優質比對。

前提資料準備

建立索引

PUT /sms-logs-index
{
  "settings": {
    "number_of_replicas": 1,
    "number_of_shards": 5
  },
  
  "mappings": {
    "sms-logs-type":{
      "properties":{
        "corpName":{
          "type":"keyword"
        },
        "smsContent":{
          "type":"text",
          "analyzer":"ik_max_word"
        },
        "fee":{
          "type":"long"
        },
        "province":{
          "type":"keyword"
        },
        "create":{
          "type":"date",
          "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        }
      }
    }
  }
}
           

導入資料,可以自己随便編寫資料。編寫10條左右即可

POST /sms-logs-index/sms-logs-type
{
   "corpName":"中國聯通",
  "smsContent":"歡迎您來到齊魯大地,祝您平安愉快!撥打漫遊地區号+12580訂票訂房;辦理移動業務,請撥10086咨詢;中國聯通山東公司将竭誠為您服務。",
  "fee":"30",
  "province":"山東",
  "create":"2020-05-19"
}
           
  1. match_all查詢
    查詢所有,相當于沒有任何查詢條件。預設size為10
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "match_all": {}
      }
    }
               
  2. match查詢

    進階查詢,不同字段類型采用不同的查詢方式

    日期或者數字,自動轉

    keyword,不會分詞

    text,會自動分詞

    # match查詢
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "match": {
          "smsContent": "中國電信"
        }
      }
    }
    # 注意:中國電信會被分詞為:中國移動、中國移、中國、移動。是以隻要文檔的smsContent字段内容包含了這四個詞的,都會被查出來,僅僅是分數會低一下,比如有的内容隻出現了[中國]
    
    
    # 現在更新為"smsContent": "齊魯",則展示結果如下
    {
      "took" : 1,
      "timed_out" : false,
      "_shards" : {
        "total" : 5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : 1,
        "max_score" : 1.2005384,
        "hits" : [
          {
            "_index" : "sms-logs-index",
            "_type" : "sms-logs-type",
            "_id" : "PLNYcHMB9IjDRQti4nhj",
            "_score" : 1.2005384,
            "_source" : {
              "corpName" : "中國聯通",
              "smsContent" : "歡迎您來到齊魯大地,祝您平安愉快!撥打漫遊地區号+12580訂票訂房;辦理移動業務,請撥10086咨詢;中國聯通山東公司将竭誠為您服務。",
              "fee" : "30",
              "province" : "山東",
              "create" : "2020-05-19"
            }
          }
        ]
      }
    }
    
    
    # 布爾match查詢
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "match": {
          "smsContent": {
            "query": "齊魯 大地",
            "operator": "or"
          }
        }
      }
    }
               
  3. mutil_match查詢
    之前是針對一個field的内容做value檢索,mutil_match則是針對多個filed中對該value做檢索
    #mutil_match查詢
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "multi_match": {
          "query": "中國熱線",
          "fields": ["corpName","smsContent"]
        }
      }
    }
    
    # 中國熱線,在corpName不會被分詞,在smsContent會被分詞
               
  4. term查詢

    代表完全比對。不會分詞,直接去分詞庫中比對内容,是以很适合string文本類型為keyword類型的。

    以“奮鬥的時代”為例:使用ik分詞器分為:奮鬥,奮,鬥,時代。但是term和terms是不分詞的,是以ik分詞器中是沒有“奮鬥的時代”這5個字的詞語,是以就查詢不到。即使後面正在的完整句子有改5個字的詞語。

    POST /sms-logs-index/sms-logs-type/_search
    {
      "from": 0,
      "size": 20,
      "query": {
        "term": {
          "corpName": {
            "value": "中國移動"
          }
        }
      }
    }
               
  5. terms查詢
    機制跟term一緻,不過它可以針對一個field字段的内容包含多個值的時候使用。如同sql中or。省份為北京或者上海或者遼甯
    POST /sms-logs-index/sms-logs-type/_search
    {
      "from": 0,
      "size": 20,
      "query": {
        "terms": {
          "province": [
            "遼甯",
            "山東"
          ]
        }
      }
    }
               
  6. id查詢
    直接根據文檔的id擷取某一條資料
    GET /sms-logs-index/sms-logs-type/PrNjcHMB9IjDRQtiY3hb
               
  7. ids查詢
    根據多個id擷取
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "ids": {
          "values": ["NrNWcHMB9IjDRQtiK3iX","PrNjcHMB9IjDRQtiY3hb"]
        }
      }
    }
               
  8. fuzzy模糊糾正查詢
    根據查詢詞語,大概的去查詢資料。注意是大概,也就是很不穩定,因為查詢詞語可以是有錯别字等。比如,想去比對盒馬鮮生,輸入河馬先生也是有可能查詢的到。但是差距太大,則也有可能差不多。是以穩定性差
    # 改為中國一動可以查詢的到,但是改為中國yi動則查詢不到
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "fuzzy": {
          "corpName": {
            "value": "中國一動"
          }
        }
      }
    }
    # 前面3個字元一樣,這樣的話就查詢不到了
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "fuzzy": {
          "corpName": {
            "value": "中國一動",
            "prefix_length": 3
          }
        }
      }
    }
               
  9. prefix字首查詢
    可以根據想搜尋字段的前面的一部分去搜尋。不僅僅适合text類型,也适用于keyword關鍵字類型的。都能查出
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "prefix": {
          "smsContent": {
            "value": "尊敬"
          }
        }
      }
    }
               
  10. wildcard通配查詢

    跟mysql的like查詢類似。通配符*為多個未知字元,?為一個字元。

    非常消耗資源

    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "wildcard": {
          "corpName": {
            "value": "??電信"
          }
        }
      }
    }
    
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "wildcard": {
          "smsContent": {
            "value": "*荊楚"
          }
        }
      }
    }
               
  11. regexp正則查詢

    正則比對的查詢

    以上fuzzy、prefix、wildcard和regexp查詢效率低,耗費資源的。字首比對是優于wildcard和regexp。

    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "regexp": {
          "corpName": "中國聯通[0-9]{2}"
        }
      }
    }
    
    # 有一個資料 "corpName" : "中國聯通12"。是以該正則可以查到資料
               
  12. rang數字範圍查詢
    範文查詢,針對數字
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "range": {
          "fee": {
            "gte": 100,
            "lte": 200
          }
        }
      }
    }
               
4、進階查詢
  1. delete_by_query
    根據match或者term等基本查詢操作查詢到的資料進行删除
    POST /sms-logs-index/sms-logs-type/_delete_by_query
    {
      "query":{
        "range":{
          "fee":{
            "gte": 3000
          }
        }
      }
    }
    # 結果如下deleted為2,删除了2條
    {
      "took" : 32,
      "timed_out" : false,
      "total" : 2,
      "deleted" : 2,
      "batches" : 1,
      "version_conflicts" : 0,
      "noops" : 0,
      "retries" : {
        "bulk" : 0,
        "search" : 0
      },
      "throttled_millis" : 0,
      "requests_per_second" : -1.0,
      "throttled_until_millis" : 0,
      "failures" : [ ]
    }
               
  2. bool查詢

    過濾器查詢,将多個查詢調教,以一定邏輯操作組合到一起

    must:相當于都符合,and

    must_not:相當于都不符合,not

    should:相當于或者,or

    filter:不計算分數,對經常過濾的資料進行緩存

    # 省份為湖北或者北京
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "term": {
                "province": {
                  "value": "湖北"
                }
              }
            },
             {
              "term": {
                "province": {
                  "value": "北京"
                }
              }
            }
          ]
        }
      }
    }
    
    #公司不是中國移動
    #短信内容包含中國和大地
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "bool": {
        
          "must_not": [
            {
              "term": {
                "corpName": {
                  "value": "中國移動"
                }
              }
            }
          ],
          "must": [
            {
              "match": {
                "smsContent": "中國"
              }
            },
            {
              "match": {
                "smsContent": "大地"
              }
            }
          ]
        }
      }
    }
    
    # 【注意】must和should混合使用的時候,發現should不起作用了。這個時候可以根據嚴謹的資料邏輯編寫查詢語句
    
    # filter查詢
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "bool": {
          "filter": [
            {
              "term":{
                "corpName": "中國移動"
              }
            },
            {
              "range":{
                "fee":{
                  "gte": 3000
                      }
                }
            }
            ]
        }
      }
    }
               
  3. filter查詢

    query:查詢到的文檔的比對度會得到分數,并且排序,不會緩存,适合實時查詢

    filter:查詢到的文檔不會計算分數,而是會對經常被過濾的資料進行緩存

    # filter查詢
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "bool": {
          "filter": [
            {
              "term":{
                "corpName": "中國移動"
              }
            },
            {
              "range":{
                "fee":{
                  "gte": 3000
                      }
                }
            }
            ]
        }
      }
    }
               
  4. boosting查詢

    提升分數查詢。預設按照分數,但是有時候想改變一下排序權重

    通過将文檔原本的_score和negative_boost參數進行相乘來得到新的_score。

    positive查詢:比對到了positive查詢的文檔才會被包含到結果集中

    negative查詢:滿足positive之後,又滿足negative,則比對的文檔會被降低其相關度

    negative_boost系數小于1.0

    # 正常查詢
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "match": {
              "smsContent": "北京"
            }
      }
    }
    
    #boosting查詢
    #短信内容有北京的,公司為中國移動的,則降低其分數
    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "boosting": {
          "positive": {
            "match": {
              "smsContent": "北京"
            }
          },
          "negative": {
            "match": {
              "corpName": "中國移動"
            }
          },
          "negative_boost": 0.2
        }
      }
    }
               
  5. 高亮查詢

    查詢的語句會被高亮顯示。

    高亮的資料不會影響原來的資料,而是單獨将filed對應的資料以高亮傳回

    POST /sms-logs-index/sms-logs-type/_search
    {
      "query": {
        "term": {
          "smsContent": "荊楚"
        }
      }
      ,
      "highlight": {
        "fields": {
          "smsContent": { 
            "pre_tags": "<font color='red'>",
            "post_tags": "</font>",
            "fragment_size": 10
          }
        }
      }
    }
    
    #結果
         {
            "_index" : "sms-logs-index",
            "_type" : "sms-logs-type",
            "_id" : "PbNicHMB9IjDRQti4Hgh",
            "_score" : 1.1748445,
            "_source" : {
              "corpName" : "中國電信",
              "smsContent" : "歡迎您來到荊楚大地大地,祝您平安愉快!撥打漫遊地區号+12580訂票訂房;辦理移動業務,請撥10086咨詢;中國電信荊州公司将竭誠為您服務。",
              "fee" : "30",
              "province" : "湖北",
              "create" : "2020-05-19"
            },
            "highlight" : {
              "smsContent" : [
                "歡迎您來到<font color='red'>荊楚</font>大地大地"
              ]
            }
          }
               
  6. 聚合查詢

    使用aggs。在查詢資料的最後單獨展示

    1、去重計數cardinality

    2、範圍統計range。數值range,時間範圍date_range,ip範圍ip_date。from包含,to不包含。

    3、統計查詢extended_stats,最大值,最小值,平均值等

  7. 經緯度查詢

    根據地點在地圖的坐标,來确定一個範圍。看某個點在不在範圍中。字段filed的類型為geo_point。

    确定範圍有,以直線确定一個圓;以2個點确定一個矩形;多個點連接配接為多邊形來确定一個範圍。

自此es基礎版筆記記錄完畢,若想檢視es進階功能和原理,請點選es進階版筆記(待續)

若想安裝es和kibana可以移步至docker安裝es和kibana——非常簡單

【暫完】

正在去BAT的路上修行