ElasticSearch基本語法


介紹

Elasticsearch 是一個分布式的免費開源搜索和分析引擎,適用於包括文本、數字、地理空間、結構化和非結構化數據等在內的所有類型的數據。

官方文檔

官方介紹

其特點是:

  • 一個分布式的實時文檔存儲,每個字段 可以被索引與搜索
  • 一個分布式實時分析搜索引擎
  • 能勝任上百個服務節點的擴展,並支持 PB 級別的結構化或者非結構化數據

基本概念

1、Index(索引)

動詞:相當於MySQL的insert;

名詞:相當於MySQL的Database。

2、Type(類型)

在Index中,可以定義一個或多個類型。類似於MySQL中的Table,每一種類型的數據放在一起。

3、Document(文檔)

保存在某個索引(Index)下,某種類型(Type)的一個數據(Document),文檔是JSON格式的,Document就像是MySQL中的某個Table里面的內容。

4、倒排索引

在存儲數據時,ES會將整句拆分為單詞,以單詞來反向檢索整句。

docker安裝ES

docker安裝elasticsearch

初步檢索

1、_cat

GET/_cat/nodes    //查看所有節點
GET/_cat/health   //查看es健康狀況
GET/_cat/master   //查看主節點
GET/_cat/indices  //查看所有索引

2、索引一個文檔(保存)

//在customer索引下的external類型下保存1號數據為
PUT customer/external/1
{
    "name":"John Doe"
}

PUT和POST都可以:

  • POST新增。如果不指定id,會自動生成id。指定id就會修改這個數據,並新增版本號。
  • PUT可以新增可以修改。PUT必須指定id,由於PUT需要指定id,我們一般用來做修改操作,不指定id會報錯。

3、查詢文檔

GET customer/external/1

//結果:
{ 
  "_index" : "customer",    //索引
  "_type" : "external",     //類型
  "_id" : "1",              //記錄id
  "_version" : 1,           //版本號
  "_seq_no" : 0,            //並發控制字段,每次更新就會+1,用來做樂觀鎖
  "_primary_term" : 1,      //同上,主分片重新分配,如重啟,就會變化
  "found" : true,
  "_source" : {
    "name" : "John Doe"
  }
}

//可以用_seq_no和_primary_term做並發時的樂觀鎖
//在更新時攜帶當前的這兩個值,后台更新時如發現這兩個值已經變化了(即更新過)則會更新失敗
//?if_seq_no=1&if_primary_term=1

4、更新文檔

//該方法會對比原來數據,如果數據與原來一樣,則什么都不做
POST customer/external/1/_update
{
    "doc" : {
        "name":"John Doew"
    }
}

//或者 不帶update則不會檢查原數據,會一直更新
POST customer/external/1
{
    "name":"John Doe2"
}

//或者
PUT customer/external/1
{
    "name":"John Doe2"
}

//更新同時增加屬性  不帶update也可以
POST customer/external/1/_update
{
    "doc":{"name":"Jane Doe","age":20}
}

5、刪除文檔&索引

//刪除文檔
DELETE customer/external/1
//刪除索引  不能直接刪除類型
DELETE customer

6、bulk批量API

POST customer/external/_bulk
{"index":{"_id":"1"}}
{"name":"John Doe"}
{"index":{"_id":"2"}}
{"name":"John Doe"}

//語法格式
{action:{metadata}}\n
{request body}\n

進階檢索

1.准備

為了測試更復雜的情況,需要將官方提供的測試數據用批量命令進行導入。

//命令是
POST bank/account/_bulk
//后跟上面的測試數據

2. 基本語法

//查詢語句的典型結構
{
    QUERY_NAME:{
        ARGUMENT:VALUE,
        ARGUMENT:VALUE,
    }
}

//例子
GET bank/_search
{
  //查詢條件
  "query": {
    "match_all": {}   
  },
  //排序方式
  "sort": [
    {
      "account_number": "asc"
    } ,
    {
      "balance": "desc"
    }
  ],
  //分頁
  "from": 0,
  "size": 20,
  //顯示哪些信息
  "_source": ["balance", "firstname"]
}

3. match

全文匹配,如果是數值類型會進行完全匹配,如果是字符串類型則會對檢索條件進行分詞匹配,返回的結果會按得分從高到低排列。

如果字符串類型的要匹配精確的值,可在字段后面加上.keyword

GET bank/_search
{
  "query": {
    "match": {
      "balance": 16418
    }
  }
}

//查到了19條記錄
GET bank/_search
{
  "query": {
    "match": {
      "address": "Mill lane"
    }
  }
}

4. math_phrase

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

//只能查到一條記錄
GET bank/_search
{
  "query": {
    "match_phrase": {
      "address": "Mill lane"
    }
  }
}

5. multi_match

多字段匹配,即多個字段匹配檢索條件。

//address和city會分別與mill和movico進行匹配
GET bank/_search
{
  "query": {
    "multi_match": {
      "query": "mill movico",
      "fields": ["address","city"]
    }
  }
}

6. bool復合查詢

GET bank/_search
{
  "query": {
    "bool": {
      //必須滿足
      "must": [
        {
          "match": {
            "gender": "M"
          }
        },
        {  
          "match": {
            "address": "mill"
          }
        }
      ],
      //必須不是  相當於過濾器
      "must_not": [
        {
          "match": {
            "age": 28
          }
        }
      ],
      //應該滿足 滿足了分數會相應提高,不滿足不會被過濾掉
      "should": [
        {
          "match": {
            "lastname": "Hines"
          }
        }
      ]
    }
  }
}

7. filter

//filter就是一個過濾器.能夠對查詢到的結果進行過濾,且不會貢獻相關性得分
GET bank/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "age": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ]
    }
  }
}

8. term

和match一樣,匹配某個屬性的值。

建議:全文檢索字段用match,其他非text字段匹配用term

GET bank/_search
{
  "query": {
    "term": {
      "balance": {
        "value": 32838
      }
    }
  }
}

//完全匹配,不能查到數據
GET bank/_search
{
  "query": {
    "match": {
      "address.keyword": "798 Farragut"
    }
  }
}
//對比上面,短語匹配,能查到一條數據
GET bank/_search
{
  "query": {
    "match_phrase": {
      "address": "798 Farragut"
    }
  }
}  

聚合(aggregations)

聚合提供了從數據中分組和提取數據的能力。最簡單的聚合方法大致等於SQL GROUP BY和SQL聚合函數。在ES中,執行搜索會返回hits(命中結果),並且同時返回聚合結果,把一個響應中的所有hits分隔開的能力。

//搜索address中包含mill的所有人的年齡分布以及平均年齡
GET bank/_search
{
  "query": {
    "match": {
      "address": "mill"
    }
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 10
      }
    },
    "ageAvg":{
      "avg": {
        "field": "age"
      }
    }
  }
}

//返回的聚合結果為
"aggregations" : {
    "ageAgg" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 0,
        "buckets" : [
            {
                "key" : 38,
                "doc_count" : 2
            },
            {
                "key" : 28,
                "doc_count" : 1
            },
            {
                "key" : 32,
                "doc_count" : 1
            }
        ]
    },
    "ageAvg" : {
        "value" : 34.0
    }
}


//按照年齡聚合,並且請求這些年齡段的平均薪資
GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 3
      },
      "aggs": {
        "avgAgg": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}
//返回的結果
"aggregations" : {
    "ageAgg" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 820,
        "buckets" : [
            {
                "key" : 31,
                "doc_count" : 61,
                "avgAgg" : {
                    "value" : 28312.918032786885
                }
            },
            {
                "key" : 39,
                "doc_count" : 60,
                "avgAgg" : {
                    "value" : 25269.583333333332
                }
            },
            {
                "key" : 26,
                "doc_count" : 59,
                "avgAgg" : {
                    "value" : 23194.813559322032
                }
            }
        ]
    }
}

映射(Mapping)

映射是定義文檔及其包含的字段的存儲和索引方式的過程。

每個文檔都是字段的集合,每個字段都有自己的 數據類型。映射數據時,您將創建一個映射定義,其中包含與文檔相關的字段列表。映射定義還包括元數據字段,例如該 _source字段,用於自定義如何處理文檔的關聯元數據。

使用動態映射顯式映射來定義數據。每種方法都會根據您在數據旅途中的位置提供不同的好處。例如,將字段顯式映射到您不想使用默認值的位置,或者獲得對創建哪些字段的更大控制權。然后,您可以允許Elasticsearch動態添加其他字段。

1. 創建一個索引並且指定映射

PUT /my-index-000001
{
  "mappings": {
    "properties": {
      "age":    { "type": "integer" },  
      "email":  { "type": "keyword"  }, 
      "name":   { "type": "text"  }     
    }
  }
}

2. 在索引中添加映射

PUT /my-index-000001/_mapping
{
  "properties": {
    "addr": { "type": "keyword" }
  }
}

3. 更新映射

不能更新映射。

4. 數據遷移

//先創建出new_twitter的正確映射
//然后使用如下方式進行數據遷移
POST _reindex [固定寫法]
{
    "source":{
        "index": "twitter",
        "type": "tweet" //如果有類型需加上
    },
    "dest":{
        "index": "new_twitter"
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM