@TOC
es的基礎(chǔ)概念
1.cluster(集群)
一個集群就是由一個或多個es節(jié)點組織在一起,它們共同持有整個的數(shù)據(jù),并一起提供索引和搜索功能,一個集群由一個唯一的名字標(biāo)識,這個名字默認(rèn)就是“elasticsearch”,多個節(jié)點使用這個名字加入集群、每個節(jié)點都有自己的名字,集群是通過集群的名字來加入一個集群的。另外,每一個集群節(jié)點都有它自己的名字。如上節(jié)中所講的,master、salve1、slave2等。
2.node(節(jié)點)
一個節(jié)點是集群中的一個es實例,作為集群的一部分,它存儲你的數(shù)據(jù),參與集群的索引和搜索功能,和集群類似,一個節(jié)點也是由一個名字來標(biāo)識,默認(rèn)情況下,不配置會使用隨機(jī)名稱,這個明早再會在啟動的時候賦予節(jié)點
3.Index(索引)
一個索引就是一個擁有相似特征的文檔集合(類似mysql的數(shù)據(jù)庫),一個索引由一個名字來標(biāo)識,我們對索引中的文檔進(jìn)行索引、搜索時都需要用到這個名字
4.type(類型)
一個索引中,可以定義一個或多個類型,一個類型相當(dāng)于索引的一個分類(類似myql的表)
5.document(文檔)
一個文檔是一個可被索引的基礎(chǔ)信息單元(類似表中的一行記錄),它是最小的存儲單元,比如說一個用戶的基本信息,一篇文章的數(shù)據(jù)等等,文檔以json格式來表示。
6.Mapping(映射)
Mapping是對類型中的文檔中的每個字段進(jìn)行預(yù)先定義數(shù)據(jù)類型等功能,如定義文檔中的某個字段為整形,使用什么分析器,是否可搜索等,一個索引可以定義多個mapping
7.Shards (分片)
Shard代表索引分片,es可以把一個完整的索引分成多個分片保存到不同的節(jié)點上,這樣的好處是可以把一個大的索引拆成多個,分布到不同的節(jié)點上,構(gòu)成分布式搜索,分片的數(shù)量只能在索引創(chuàng)建前指定,索引創(chuàng)建或不能修改
8.Replicas(副本)
代表索引副本,es可以對一個分片設(shè)置多個副本,副本的作用是提高系統(tǒng)的容錯性,當(dāng)每個節(jié)點某個分片損壞或丟失時可以從副本中恢復(fù),二是提供es的搜索效率,es會對搜索請求進(jìn)行負(fù)載均衡。
當(dāng)一個主分片失敗或者出現(xiàn)問題時,代替的分片就會代替其工作,從而提高了es的可用性,那么備份的分片還可以支持搜索操作,以分?jǐn)偹阉鞯膲毫Αs在創(chuàng)建索引時,會創(chuàng)建5個分片,一份備份,這個數(shù)量是可以修改的,備份是可以動態(tài)修改的。
物理設(shè)計
一個人就是一個集群
es在后臺把每個索引劃分成多個分片,每份分片可以在集群中的不同服務(wù)器間遷移。
一個人就是一個集群!默認(rèn)的集群名稱就是elasticsearch。

節(jié)點和分片如何工作
默認(rèn)分片是5個,創(chuàng)建副本是1個,意思就是我們存的數(shù)據(jù)通過這個分片可以搭到不同的節(jié)點上,一個集群至少有一個節(jié)點,而一個節(jié)點就是一個es進(jìn)程,節(jié)點可以有多個索引默認(rèn)的,如果你創(chuàng)建索引,那么索引將會有5個分片(primary shard,又稱為主分片)構(gòu)成的,每一個主分片會有一個副本(replica shard,又稱復(fù)制分片)如下:

下圖是一個有3個節(jié)點的集群,可以看見主分片和對應(yīng)的副本分片都不會在同一節(jié)點內(nèi),這樣的好處在于某一個節(jié)點掛了,數(shù)據(jù)不至于丟失。實際上,一個分片是一個Lucene索引,一個包含倒排索引的文件目錄,倒排索引的結(jié)構(gòu)使得es在不掃描全部文檔的情況下,就能告訴你哪些文檔包含特定的關(guān)鍵詞。

ElasticSearch VS Solr
- Solr 利用 Zookeeper 進(jìn)行分布式管理,而 Elasticsearch 自身帶有分布式協(xié)調(diào)管理功能;
- Solr 支持更多格式的數(shù)據(jù),而 Elasticsearch 僅支持json文件格式;
- Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高級功能多有第三方插件提供;
- Solr 在傳統(tǒng)的搜索應(yīng)用中表現(xiàn)好于 Elasticsearch,但在處理實時搜索應(yīng)用時效率明顯低于 Elasticsearch。
- Solr 是傳統(tǒng)搜索應(yīng)用的有力解決方案,但 Elasticsearch 更適用于新興的實時搜索應(yīng)用。
es的RESTFul API
- API的基本格式http://<ip>:<port>/<索引>/<類型>/<文檔id>
- 常用HTTP動詞GET/PUT/POST/DELETE
索引創(chuàng)建
索引的創(chuàng)建主要分結(jié)構(gòu)化和非結(jié)構(gòu)化創(chuàng)建
結(jié)構(gòu)化創(chuàng)建
點擊索引->新建索引,輸入book,默認(rèn)分片數(shù)為5,副本數(shù)為1,然后再到概覽里面就可以看見我們創(chuàng)建的book索引了,粗線框是主分片,而細(xì)線框是粗線線框的備份分片。
非結(jié)構(gòu)化創(chuàng)建
索引的創(chuàng)建分為結(jié)構(gòu)化和非結(jié)構(gòu)化,那么如何區(qū)分結(jié)構(gòu)化和非機(jī)構(gòu)化的呢?在Head插件頁面上點擊信息->索引信息,可以看見一個關(guān)鍵詞mappings,這關(guān)鍵詞如果為空的,那么就為非結(jié)構(gòu)化的索引。
創(chuàng)建結(jié)構(gòu)化索引,在復(fù)合查詢中,輸入book/novel/_mappings,指定json結(jié)構(gòu):
{
"novel": {
"properties": {
"title": {
"type": "text"
}
}
}
}
提交一下請求,會顯示創(chuàng)建成功
{
"acknowledged":true
}
然后再點擊首頁的索引信息,就可以看見mappings就不是空的了
"mappings":
postman模擬
采用postman提交索引的新建
PUT 127.0.0.1:9200/people
{
"settings ": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"man": {
"properties": {
"name": {
"type": "text"
},
"country": {
"type": "integer"
},
"age": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
},
"woman": {
}
}
}
然后可以到head插件里面就可以看見剛才創(chuàng)建的people索引信息了
es的基本操作
插入
es的插入分為兩種,指定文檔id插入和自動產(chǎn)生文檔id插入
指定文檔id插入
我們在postman中插入:
PUT 127.0.0.1:9200/people/man/1
Body
{
"name": "keweizhou",
"country": "china",
"age": 30,
"date": "1987-03 -07"
}
- head插件里面的docs代表所有文檔值
- 點擊head里面的數(shù)據(jù)瀏覽就可以看見我們剛才插入的值了
自動產(chǎn)生文檔id插入
不加id采用POST方式提交,es默認(rèn)會自己幫你生成一個id,而不是我們指定的那個id
修改
指定文檔id修改文檔
針對文檔id為1的進(jìn)行修改
POST 127.0.0.1:9200/people/man/1/_update
body
{
"script": {
"lang": "painless",
"inline":"ctx._source.age+=10"
}
}
還可以通過參數(shù)的形式修改數(shù)據(jù),如
{
"script": {
"lang": "painless",
"inline": "ctx._source.age+=params.age",
"params": {
"age": 100
}
}
}
然后我們?nèi)ead插件里面就可以看見修改的數(shù)據(jù)了
ctx代表es的上下文,._source代表es的文檔
刪除
刪除文檔
進(jìn)入postman,調(diào)用:DELETE 127.0.0.1:9200/people/man/1
刪除索引
刪除索引有兩種方法
- 在head插件里面,動作下面有個刪除的按鍵,然后點擊刪除,就可以將其刪除了
- 或者在postman中調(diào)用 DELETE 127.0.0.1:9200/people,就可以將索引刪除了
查詢
簡單查詢
通過id為1查詢當(dāng)條記錄:GET 127.0.0.1:9200/book/novel/1
條件查詢
POST 127.0.0.1:9200/book/_serarch
查詢所有的數(shù)據(jù),body為:
{
"query": {
"match_all": {}
}
}
查詢標(biāo)題為elasticsearch的書籍:
{
"query": {
"match": {
"title": "elasticserarch"
}
}
}
也可以在后面加上條件限制
"from":1,
"size":1
指定排序字段和排序類型(默認(rèn)升序排列的):
{
"sort": [{
"publish_date": {
"order": "desc"
}
}]
}
聚合查詢
aggs是聚合查詢的關(guān)鍵詞,可以按照這些字段進(jìn)行聚合統(tǒng)計
{
"aggs": {
"group_by_word_count": {
"terms": {
"field": "word_count"
}
},
"group_by_publish_date": {
"terms": {
"field": "publish_date"
}
}
}
}
對word_count進(jìn)行數(shù)學(xué)計算
{
"aggs": {
"grades_word_count": {
"stats": {
"field": "word_count"
}
}
}
}
也可以將stats換成min、max等等進(jìn)行數(shù)學(xué)計算
高級查詢
子條件查詢(葉子條件查詢)
特定字段查詢所指特定值,它可以分為Query context和Filter context
Query context
在查詢過程中,除了判斷文檔是否滿足查詢條件外,ES還會計算一個_score來標(biāo)識匹配的程度,旨在判斷目標(biāo)文檔和查詢條件匹配的有多好。
常用查詢分為全文本查詢和字段級別查詢
普通字段匹配找出作者是keweizhou的用戶,但是用到習(xí)語就會有問題,比如我查詢java開發(fā)這個習(xí)語,就會把所有和java以及開發(fā)的都找出來,那么這個就不行了,要將match換成match_phrase
POST 127.0.0.1:9200/book/_search
{
"query": {
"match": {
"author": "keweizhou"
}
}
}
查詢習(xí)語
{
"query": {
"match_parase": {
"title": "java開發(fā)"
}
}
}
- 全文本查詢: 針對文本類型數(shù)據(jù)
- 字段級別查詢: 針對結(jié)構(gòu)化數(shù)據(jù),如數(shù)字,日期等
復(fù)合查詢是以一定邏輯組合子條件查詢,如:
查詢author和title字段中包含張三的數(shù)據(jù),語法查詢經(jīng)常在kibana中用
POST 127.0.0.1:9200/book/_search
{
"query": {
"multi_match": {
"query": "張三",
"fields": ["author", "title"]
}
}
}
語法查詢
POST 127.0.0.1:9200/book/_search
查詢出Elasticsearch和大法的信息
{
"query": {
"query_string": {
"query": "Elasticsearch AND 大法"
}
}
}
查詢Elasticsearch和大法或者Python相關(guān)的
{
"query": {
"query_string": {
"query": "(Elasticsearch AND 大法) OR Python"
}
}
}
利用query_string查詢多個字段:
{
"query": {
"query_string": {
"query": "張三 OR Elasticsearch",
"fields": ["title", "author"]
}
}
}
結(jié)構(gòu)化查詢(按照一些字段的查詢):
POST 127.0.0.1:9200/book/_search
如查詢word_count字段等于1000的信息
{
"query": {
"term": {
"word_count": 1000
}
}
}
查詢書籍字?jǐn)?shù)(word_count)在1000~2000之間的
{
"query": {
"range": {
"word_count": {
"gte": 1000,
"lte": 2000
}
}
}
}
注意: 其中的e代表equals的意思,>=或者<=中的等于,它還可以用于日期類型上
Filter context
在查詢過程中,只判斷該文檔是否滿足條件,只有Yes或者No,主要是做數(shù)據(jù)過濾的,將符合條件的數(shù)據(jù)過濾出來。
POST 127.0.0.1:9200/book/_search
{
"query": {
"bool": {
"filter": {
"term": {
"word_count": 1000
}
}
}
}
}
復(fù)合條件查詢
常用查詢?yōu)楣潭ǚ謹(jǐn)?shù)查詢、布爾查詢
固定分?jǐn)?shù)查詢
POST 127.0.0.1:9200/_search
boot為指定分?jǐn)?shù)為2,最后查詢出來的score都是2
{
"query": {
"constant_score": {
"filter": {
"match": {
"title": "ElasticSearch"
}
},
"boot": 2
}
}
}
should是一個或的關(guān)系,只要滿足其中的一個就行了。如何想要得到與的關(guān)系,那么必須將should關(guān)鍵詞換成must
{
"query": {
"bool": {
"should": [{
"match": {
"author": "張三"
}
},
{
"match": {
"title": "ElasticSearch"
}
}
]
}
}
}
還可以配合著filter一起使用,如:
{
"query": {
"bool": {
"must": [{
"match": {
"author": "張三"
}
},
{
"match": {
"title": "ElasticSearch"
}
}
],
"filter": [{
"term": {
"word_count": 1000
}
}]
}
}
}
它還有一個關(guān)鍵詞就是must_no,它的意識和must正好想法,代表的意思就是一定不相等的意思。

參考: https://github.com/nuptkwz/notes/tree/master/technology/elasticsearch