<sub id="gqw76"><listing id="gqw76"></listing></sub>
      <sub id="gqw76"><listing id="gqw76"></listing></sub>

    1. <form id="gqw76"><legend id="gqw76"></legend></form>
    2. ElasticSearch 進階

      ElasticSearch 進階

      SearchAPI

      ES 支持兩種基本方式檢索 :

      • 一個是通過使用 REST request URI 發送搜索參數(uri+檢索參數)
      • 一個是通過使用 REST request body 來發送它們(uri+請求體)

      檢索信息

      請求參數 詳情
      GET bank/_search 檢索 bank 下所有信息,包括 type 和 docs
      GET bank/_search?q=*&sort=account_number:asc 請求參數方式檢索
      響應結果解釋:
      took - Elasticsearch 執行搜索的時間(毫秒)
      time_out - 告訴我們搜索是否超時
      _shards - 告訴我們多少個分片被搜索了,以及統計了成功/失敗的搜索分片
      hits - 搜索結果
      hits.total - 搜索結果
      hits.hits - 實際的搜索結果數組(默認為前 10 的文檔) 
      sort - 結果的排序 key(鍵)(沒有則按 score 排序) 
      score 和 max_score –相關性得分和最高得分(全文檢索用)
      
      • uri+請求體
      # GET查詢 kibana查詢
      GET bank/_search
      {
        "query": {
          "match_all": {}
        },
        "sort": [
          {
            "account_number": "asc"
          },
          {
            "balance": "desc"
          }
        ]
      }
      
      HTTP 客戶端工具(POSTMAN),get 請求不能攜帶請求體,我們變為 post 也是一樣的我們 POST 一個 JSON 風格的查詢請求體到 _search API。
      需要了解,一旦搜索的結果被返回,Elasticsearch 就完成了這次請求,并且不會維護任何
      服務端的資源或者結果的 cursor(游標)
      

      Query DSL

      基本語法格式

      Elasticsearch 提供了一個可以執行查詢的 Json 風格的 DSL(domain-specific language 領域特定語言)。這個被稱為Query DSL。該查詢語言非常全面,并且剛開始的時候感覺有點復雜, 學好它的方法是從一些基礎的示例開始的。

      # 查詢語句
      {
        QUERY_NAME: { 
          ARGUMENT: VALUE, 
          ARGUMENT: VALUE,
          ...
        }
      }
      
      # 查詢語句-針對某個字段
      {
        QUERY_NAME: { 
          FIELD_NAME: {
            ARGUMENT: VALUE, 
            ARGUMENT: VALUE,
            ...
          }
        }
      }
      

      查詢-match

      # kibana查詢
      GET bank/_search
      {
        "query": {
          "match_all": {}
        },
        "from": 0,
        "size": 5,
        "sort": [
          {
            "account_number": {
              "order": "desc"
            }
          }
        ]
      }
      
      query :定義查詢
      match_all 查詢類型: 代表查詢所有的所有
      from+size 限定: 分頁功能
      sort : 排序
      
      # kibana查詢-返回部分字段
      GET bank/_search
      {
        "query": {
          "match_all": {}
        },
        "from": 0,
        "size": 5,
        "_source": ["age","balance"]
      }
      
      # kibana查詢-match查詢
      基本類型(非字符串),精確匹配;match 返回 account_number=20 的數據
      GET bank/_search
      {
        "query": {
          "match": {
            "account_number": "20"
          }
        }
      }
      
      # kibana查詢-字符串查詢
      最終查詢出 address 中包含 mill 單詞的所有記錄
      GET bank/_search
      {
        "query": {
          "match": {
            "address": "mill"
          }
        }
      }
      
      注: match 當搜索字符串類型的時候,會進行全文檢索,并且每條記錄有相關性得分。
      
      # 字符串,多個單詞(分詞+全文檢索)
      
      

      查詢-match_phrase

      不分詞匹配

      # 查出 address 中包含 mill road 的所有記錄,并給出相關性得分
      GET bank/_search
      {
        "query": {
          "match_phrase": {
            "address": "mill road"
          }
        }
      }
      

      查詢-multi_match

      多字段匹配

      # state 或 address 包含 mill 或 movico
      GET bank/_search
      {
        "query": {
          "multi_match": {
            "query": "mill Movico",
            "fields": ["state","address"]
          }
        }
      }
      

      查詢-bool復合查詢

      bool 用來做復合查詢:
      復合語句可以合并任何它查詢語句,包括復合語句,了解這一點是很重要的。
      復合語句之間可以互相嵌套,可以表達非常復雜的邏輯。

      # 查詢address必須為mill age必須為28 lastname可為helloand也可不為helloand的數據
      
      # must:必須達到 must 列舉的所有條件
      # must_not 必須不是指定的情況
      # should:應該達到 should 列舉的條件,如果達到會增加相關文檔的評分,并不會改變查詢的結果。
      
      GET bank/_search
      {
        "query": {
          "bool": {
            "must": [
              {
                "match": {
                  "address": "mill"
                }
              },
              {
                "match": {
                  "gender": "M"
                }
              }
            ],
            "must_not": [
              {"match": {
                "age": "28"
              }}
            ],
            "should": [
              {
                "match": {
                  "lastname": "Holland"
                }
              }
            ]
          }
        }
      }
      

      查詢-filter過濾

      并不是所有的查詢都需要產生分數,特別是那些僅用于 “filtering”(過濾)的文檔。為了不計算分數 Elasticsearch 會自動檢查場景并且優化查詢的執行。

      GET bank/_search
      {
        "query": {
          "bool": {
            "must": [
              {
                "range": {
                  "age": {
                    "gte": 18,
                    "lte": 30
                  }
                }
              },
              {
                "match": {
                  "address": "mill"
                }
              }
            ]
          }
        }
      }
      
      GET bank/_search
      {
        "query": {
          "bool": {
            "filter": [
              {
                "range": {
                  "age": {
                    "gte": 18,
                    "lte": 30
                  }
                }
              }
            ]
          }
        }
      }
      

      查詢-term

      和 match 一樣。匹配某個屬性的值。全文檢索字段用 match,其他非 text 字段匹配用 term。
      Term-query-Elasticsearch-Reference-7-5-Elastic.png

      # 檢索時 非text字段則使用term
      GET bank/_search
      {
        "query": {
          "term": {
            "balance": "32838"
          }
        }
      }
      
      GET bank/_search
      {
        "query": {
          "match": {
            "balance": "32838"
          }
        }
      }
      

      Aggregations

      Aggregations結構:

      "aggregations" : {
          "<aggregation_name>" : {
              "<aggregation_type>" : {
                  <aggregation_body>
              }
              [,"meta" : {  [<meta_data_body>] } ]?
              [,"aggregations" : { [<sub_aggregation>]+ } ]?
          }
          [,"<aggregation_name_2>" : { ... } ]*
      }
      

      Aggregations范例:

      # 搜索 address 中包含mill的所有人的年齡分布以及平均年齡,但不顯示這些人的詳情
      GET bank/_search
      {
        "query": {
          "match": {
            "address": "mill"
          }
        },
        "aggs": {
          "ageAgg": {
            "terms": {
              "field": "age",
              "size": 10
            }
          },
          "ageAvg":{
            "avg":{
              "field":"age"
            }
          },
          "balanceAvg":{
            "avg": {
              "field": "balance"
            }
          }
        },
        "size": 0
      }
      
      # 按照年齡聚合,并且請求這些年齡段的這些人的平均薪資
      GET bank/_search
      {
        "query": {
          "match_all": {}
        },
        "aggs": {
          "ageAgg": {
            "terms": {
              "field": "age",
              "size": 100
            },
            "aggs": {
              "ageAvg": {
                "avg": {
                  "field": "balance"
                }
              }
            }
          }
        }
      }
      
      # 查出所有年齡分布,并且這些年齡段中 M 的平均薪資和 F 的平均薪資以及這個年齡段的總體平均薪資
      GET bank/_search
      {
        "query": {
          "match_all": {}
        },
        "aggs": {
          "ageAgg": {
            "terms": {
              "field": "age",
              "size": 100
            },
            "aggs": {
              "genderAgg": {
                "terms": {
                  "field": "gender.keyword",
                  "size": 10
                },
                "aggs": {
                  "balanceAvg": {
                    "avg": {
                      "field": "balance"
                    }
                  }
                }
              },
              "ageBalanceAvg":{
                "avg": {
                  "field": "balance"
                }
              }
            }
          }
        }
      }
      

      Mapping

      Mapping 是用來定義一個文檔(document),以及它所包含的屬性(field)是如何存儲和索引的。

      查看索引
      # 查看 mapping 信息 kibana dev Tools執行
      GET bank/_mapping
      
      創建索引

      創建索引-創建索引并指定映射

      PUT /my_index
      {
        "mappings": {
          "properties": {
            "age": {"type": "integer"},
            "email": {"type": "keyword"},
            "name": {"type": "text"}
          }
        }
      }
      
      添加新字段映射
      # 添加新字段映射
      PUT /my_index/_mapping
      {
        "properties":{
          "employee_id":{
            "type":"keyword",
            "index":false
          }
        }
      }
      
      更新映射

      images/Mapping-Elasticsearch-Reference-7-5-Elastic.png
      對于已經存在的映射字段,我們不能更新。更新必須創建新的索引進行數據遷移

      # 查看存在映射
      GET /my_index/_mapping
      
      GET /bank/_search
      
      # 更新索引映射
      PUT /newbank
      {
        "mappings": {
          "properties": {
            "account_number": {
              "type": "long"
            },
            "address": {
              "type": "text"
            },
            "age": {
              "type": "integer"
            },
            "balance": {
              "type": "long"
            },
            "city": {
              "type": "keyword"
            },
            "email": {
              "type": "keyword"
            },
            "employer": {
              "type": "keyword"
            },
            "firstname": {
              "type": "text"
            },
            "gender": {
              "type": "keyword"
            },
            "lastname": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "state": {
              "type": "keyword"
            }
          }
        }
      }
      
      # 獲取新索引
      GET /newbank/_mapping
      
      數據遷移

      先創建出 new_twitter的正確映射。
      數據遷移格式:

      # elasticsearch 新版本數據遷移
      POST _reindex	[固定寫法]
      {
          "source": {
              "index": "twitter"
          },
          "dest": {
              "index": "new_twitter"
          }
      }
      
      # elasticsearch 老版本數據遷移
      # 舊索引的 type 下的數據進行遷移
      POST _reindex
      {
          "source": {
              "index": "twitter",
              "type": "tweet"
          },
          "dest": {
              "index": "tweets"
          }
      }
      

      數據遷移:

      # 查看存在映射
      GET /my_index/_mapping
      
      GET /bank/_search
      
      # 更新索引映射
      PUT /newbank
      {
        "mappings": {
          "properties": {
            "account_number": {
              "type": "long"
            },
            "address": {
              "type": "text"
            },
            "age": {
              "type": "integer"
            },
            "balance": {
              "type": "long"
            },
            "city": {
              "type": "keyword"
            },
            "email": {
              "type": "keyword"
            },
            "employer": {
              "type": "keyword"
            },
            "firstname": {
              "type": "text"
            },
            "gender": {
              "type": "keyword"
            },
            "lastname": {
              "type": "text",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                }
              }
            },
            "state": {
              "type": "keyword"
            }
          }
        }
      }
      
      GET /newbank/_mapping
      
      # 數據遷移 老版本遷移
      POST _reindex
      {
        "source": {
          "index": "bank",
          "type": "account"
        },
        "dest": {
          "index": "newbank"
        }
      }
        
      GET /newbank/_search
      
      # 不用type 老數據可以遷移過來
      

      分詞

      一個 tokenizer(分詞器)接收一個字符流,將之分割為獨立的 tokens(詞元,通常是獨立的單詞),然后輸出 tokens 流。

      例如,whitespace tokenizer 遇到空白字符時分割文本。它會將文本 "Quick brown fox!" 分割為[Quick, brown, fox!]。

      該 tokenizer(分詞器)還負責記錄各個 term(詞條)的順序或 position 位置(用于 phrase 短語和 word proximity 詞近鄰查詢),以及 term(詞條)所代表的原始 word(單詞)的 start
      (起始)和 end(結束)的 character offsets(字符偏移量)(用于高亮顯示搜索的內容)。Elasticsearch 提供了很多內置的分詞器,可以用來構建custom analyzers(自定義分詞器)。

      # 支持英文分詞器 對中文的分詞不友好
      POST _analyze
      {
        "analyzer": "standard",
        "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
      }
      

      安裝IK分詞器

      IK分詞器下載-點我傳送

      # wget下載 /mydata/elasticsearch/plugin
      $ wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
      
      # 進入docker容器
      $ docker exec -it elasticsearch /bin/bash
      $ cd /bin/
      $ elasticsearch-plugin
      $ elasticsearch-plugin -h
      
      # 列出系統的分詞器
      $ elasticsearch-plugin list
      
      # 重啟容器
      $ docker restart elasticsearch
      

      測試IK分詞器

      # ik分詞器
      POST _analyze
      {
        "analyzer": "ik_max_word",
        "text": "我是中國人"
      }
      
      # ik分詞器
      POST _analyze
      {
        "analyzer": "ik_smart",
        "text": "我是中國人"
      }
      

      自定義詞庫

      修改/mydata/elasticsearch/plugins/elasticsearch-analysis-ik-7.4.2/config中的 IKAnalyzer.cfg.xml

      # IKAnalyzer.cfg.xml 配置文件內容
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
      <properties>
              <comment>IK Analyzer 擴展配置</comment>
              <!--用戶可以在這里配置自己的擴展字典 -->
              <entry key="ext_dict"></entry>
               <!--用戶可以在這里配置自己的擴展停止詞字典-->
              <entry key="ext_stopwords"></entry>
              <!--用戶可以在這里配置遠程擴展字典 -->
              <!-- <entry key="remote_ext_dict">words_location</entry> -->
              <!--用戶可以在這里配置遠程擴展停止詞字典-->
              <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
      </properties>
      

      添加自定義詞庫:

      # 獲取 自定義詞庫的地址 一般是安裝在nginx上
      http://192.168.188.128/es/fenci.txt
      
      # IK config配置
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
      <properties>
              <comment>IK Analyzer 擴展配置</comment>
              <!--用戶可以在這里配置自己的擴展字典 -->
              <entry key="ext_dict"></entry>
               <!--用戶可以在這里配置自己的擴展停止詞字典-->
              <entry key="ext_stopwords"></entry>
              <!--用戶可以在這里配置遠程擴展字典 -->
              <entry key="remote_ext_dict">http://192.168.188.128/es/fenci.txt</entry>
              <!--用戶可以在這里配置遠程擴展停止詞字典-->
              <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
      </properties>
      
      # 重啟elasticsearch、nginx
      $ docker restart elasticsearch
      $ docker restart nginx
      
      posted @ 2021-03-09 23:38  HOsystem  閱讀(413)  評論(0編輯  收藏  舉報
      最新chease0ldman老人|无码亚洲人妻下载|大香蕉在线看好吊妞视频这里有精品www|亚洲色情综合网

        <sub id="gqw76"><listing id="gqw76"></listing></sub>
        <sub id="gqw76"><listing id="gqw76"></listing></sub>

      1. <form id="gqw76"><legend id="gqw76"></legend></form>