1. 程式人生 > 實用技巧 >ElasticSearch基礎語法

ElasticSearch基礎語法

一、elasticsearch安裝

1、在docker安裝elasticsearch

  1. 拉取映象
$ docker pull elasticsearch:7.4.2 # 拉取elasticsearch
$ docker pull kibana:4.7.2		  # 拉取kibana,視覺化工具
  1. 基本配置
$ mkdir -p /mydata/elasticsearch/config
$ mkdir -p /mydata/elasticsearch/data
$ echo "http.host: 0.0.0.0" >/mydata/elasticsearch/config/elasticsearch.yml		# 設定埠訪問
$ chmod -R 777 /mydata/elasticsearch/
  1. 啟動
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data/:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2		# 啟動elasticsearch
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.2:9200 -p 5601:5601 -d kibana:7.4.2 # 啟動kibana

二、常用命令

1. 基本命令

1、_cat

/_cat/nodes					# 檢視所有節點
/_cat/health				# 檢視es健康狀態
/_cat/master				# 檢視主節點
/_cat/indices				# 檢視所有索引

2、索引一個文件(儲存)

post/put 請求
http://{url}/{index}/{type}/{id}[?if_seq_no=0&if_primary_term=1]
  • POST 新增。如果不指定id,會自動生成id。指定id就會修改這個資料,並新增版本號

  • PUT可以新增可以修改。PUT必須指定id;由於PUT需要指定 id,我們一般都用來做修改操作,不指定id會報錯。

  • 最後為條件修改,僅在符合條件時修改

3、查詢文件

get  請求
http://{url}/{index}/{type}

結果:

{
    "_index": "customer",			// 在哪個索引
    "_type": "external",			// 在哪個型別
    "_id": "1",						// 記錄id
    "_version": 6,					// 版本號
    "_seq_no": 5,					// 併發控制欄位,用於做樂觀鎖
    "_primary_term": 1,				// 同上,主分片重新分配,如重啟就有變化
    "found": true,					
    "_source": {					// 真正資料
        "name": "hu xin hu"
    }
}

4、更新文件

post/put 請求
http://{url}/{index}/{type}/{id}/_update
  • _update的更新,如果資料一致不做任何操作

    • 需要按著如下格式傳送請求

    • {
          "doc":{
              "name": "leo"
          }
      }
      
  • 不帶的無論如何都會操作

    • {
          "name": "leo"
      }
      

2. Query DSL

(1)基本語法格式

Elasticsearch提供了一個可以執行查詢的Json風格的DSL。這個被稱為Query DSL,該查詢語言非常全面。

一個查詢語句的典型結構

QUERY_NAME:{
   ARGUMENT:VALUE,
   ARGUMENT:VALUE,...
}

query定義如何查詢;

  • match_all查詢型別【代表查詢所有的所有】,es中可以在query中組合非常多的查詢型別完成複雜查詢;
  • 除了query引數之外,我們可也傳遞其他的引數以改變查詢結果,如sort,size;
  • from+size限定,完成分頁功能;
  • sort排序,多欄位排序,會在前序欄位相等時後續欄位內部排序,否則以前序為準;

(2)返回部分欄位

GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 5,
  "sort": [
    {
      "account_number": {
        "order": "desc"
      }
    }
  ],
  "_source": ["balance","firstname"]
  
}

(3)match匹配查詢

  • 基本型別(非字串),精確控制
  • 字串,全文檢索
  • 全文檢索,最終會按照評分進行排序,會對檢索條件進行分詞匹配。
GET bank/_search
{
  "query": {
    "match": {
      "account_number": "20"
    }
  }
}

(4) match_phrase [短句匹配]

將需要匹配的值當成一整個單詞(不分詞)進行檢索

GET bank/_search
{
  "query": {
    "match_phrase": {
      "address": "mill road"
    }
  }
}

(5)multi_math【多欄位匹配】

GET bank/_search
{
  "query": {
    "multi_match": {
      "query": "mill",
      "fields": [
        "state",
        "address"
      ]
    }
  }
}

(6)bool用來做複合查詢

  • must:必須達到must所列舉的所有條件
  • must_not:必須不匹配must_not所列舉的所有條件。
  • should:應該滿足should所列舉的條件。
GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "gender": "M"
          }
        },
        {
          "match": {
            "address": "mill"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "age": "38"
          }
        }
      ]
    }
  }
}

should:應該達到should列舉的條件,如果到達會增加相關文件的評分,並不會改變查詢的結果。如果query中只有should且只有一種匹配規則,那麼should的條件就會被作為預設匹配條件二區改變查詢結果。

(7)Filter【結果過濾】

並不是所有的查詢都需要產生分數,特別是哪些僅用於filtering過濾的文件。為了不計算分數,elasticsearch會自動檢查場景並且優化查詢的執行。

GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "address": "mill"
          }
        }
      ],
      "filter": {
        "range": {
          "balance": {
            "gte": "10000",
            "lte": "20000"
          }
        }
      }
    }
  }
}

(8)term

和match一樣。匹配某個屬性的值。全文檢索欄位用match,其他非text欄位匹配用term。

GET bank/_search
{
  "query": {
    "term": {
      "address": "mill Road"
    }
  }
}

全文檢索欄位用match,其他非text欄位匹配用term

(9)Aggregation(執行聚合)

聚合提供了從資料中分組和提取資料的能力。最簡單的聚合方法大致等於SQL Group by和SQL聚合函式。在elasticsearch中,執行搜尋返回this(命中結果),並且同時返回聚合結果,把以響應中的所有hits(命中結果)分隔開的能力。這是非常強大且有效的,你可以執行查詢和多個聚合,並且在一次使用中得到各自的(任何一個的)返回結果,使用一次簡潔和簡化的API避免網路往返。

“size”:0
size:0不顯示搜尋資料

查出所有年齡分佈,並且這些年齡段中M的平均薪資和F的平均薪資以及這個年齡段的總體平均薪資

GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 100
      },
      "aggs": {
        "genderAgg": {
          "terms": {
            "field": "gender.keyword"
          },
          "aggs": {
            "balanceAvg": {
              "avg": {
                "field": "balance"
              }
            }
          }
        },
        "ageBalanceAvg": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  },
  "size": 0
}

3. Mapping

(1)欄位型別

(2)對映

Maping是用來定義一個文件(document),以及它所包含的屬性(field)是如何儲存和索引的。比如:使用maping來定義:

  • 哪些字串屬性應該被看做全文字屬性(full text fields);
  • 哪些屬性包含數字,日期或地理位置;
  • 文件中的所有屬性是否都嫩被索引(all 配置);
  • 日期的格式;
  • 自定義對映規則來執行動態新增屬性;
  • 檢視mapping資訊

    GET bank/_mapping
    
  • 更新對映

對於已經存在的欄位對映,我們不能更新。更新必須建立新的索引,進行資料遷移。

  • 資料遷移

先建立new_twitter的正確對映。然後使用如下方式進行資料遷移。

POST reindex [固定寫法]
{
  "source":{
      "index":"twitter"
   },
  "dest":{
      "index":"new_twitters"
   }
}

舊版本

POST reindex [固定寫法]
{
  "source":{
      "index":"twitter",
      "twitter":"twitter"
   },
  "dest":{
      "index":"new_twitters"
   }
}

4. 分詞

elasticsearch提供了很多內建的分詞器,可以用來構建custom analyzers(自定義分詞器)。

內建分詞器僅支援英文,中文分詞需要自己安裝ik分詞器外掛

(1)安裝ik分詞器

  1. 下載分詞器
wget $ik分詞器下載路徑
  1. 解壓縮
unzip $檔名
  1. 重啟docker
docker restart elasticsearch

(2)自定義詞庫

  • 修改/mydata/elasticsearch/plugins/ik/config中的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">http://ip/es/fenci.txt</entry> 
	<!--使用者可以在這裡配置遠端擴充套件停止詞字典-->
	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>