【ElasticSearch】基本概念與基本語法

1、基本概念

一、Cluster(集羣)

es集羣對外提供索引和搜索的服務,其包含一個或者多個節點,每一個節點都有統一的集羣名稱。參考本地集羣搭建node

image.png

二、Node(節點)

單獨一個Elasticsearch服務器實例稱爲一個node,node是集羣的一部分,每一個node有獨立的名稱,默認是啓動時獲取一個UUID做爲名稱,也能夠自行配置。git

三、Shard(分片)

Shard分片也稱爲primary shard,是單個Lucene索引,因爲單臺機器的存儲容量是有限的,而Elasticsearch索引的數據可能特別大,單臺機器沒法存儲所有數據,就須要將索引中的數據切分爲多個shard,分佈在多臺服務器上存儲。利用shard能夠很好地進行橫向擴展,存儲更多數據,讓搜索和分析等操做分佈到多臺服務器上去執行,提高集羣總體的吞吐量和性能。建立索引時就應該預估好須要的分片數量,一旦建立則分片數量沒法更改。github

四、Replica(複製分片)

replica全稱叫replica shard,是索引的副本,徹底拷貝shard的內容,shard與replica的關係能夠是一對多,同一個shard能夠有一個或多個replica。當集羣中有節點宕機了,丟失的shard會由replica補位,保證數據高可用;replica shard也能分擔查詢請求,提高集羣的吞吐量。數據庫

五、Index(索引)

es索引,其保存具備相同結構的文檔集合,相似於關係型數據庫的數據庫實例(6.0.0版本type廢棄後,索引的概念降低到等同於數據庫表的級別)。一個集羣裏能夠定義多個索引json

六、Type(類型)

類型,本來是在索引(Index)內進行的邏輯細分,但後來發現企業研發爲了加強可閱讀性和可維護性,制訂的規範約束,同一個索引下不多還會再使用type進行邏輯拆分(如同一個索引下既有訂單數據,又有評論數據),於是在6.0.0版本以後,此定義廢棄。segmentfault

七、Document(文檔)

Elasticsearch最小的數據存儲單元,JSON數據格式,相似於關係型數據庫的表記錄(一行數據),結構定義多樣化,同一個索引下的document,結構儘量相同。api

八、Field type(字段類型)

  • text:被分析索引的字符串類型
  • keyword:不能被分析,只能被精確匹配的字符串類型
  • date:日期類型,能夠配合format一塊兒使用
  • long:長整型,數字類型
  • integer:整型,數字類型
  • short:短整型,數字類型
  • double:雙精度浮點型,數字類型
  • Boolean:布爾型,true、false
  • array:數組類型
  • object:對象類型,json嵌套
  • ip:ip類型
  • geo_point:地理位置類型

九、分詞器

ElasticSearch藉助各類類型的分詞器來對文檔內容進行分詞處理,以便於建立倒排索引,這是搜索的核心。同時也對搜索內容進行分詞處理,用以在倒排索引中索引文檔。數組

一、內置分詞器

標準分詞器(standard analyzer)(默認)
  • 分析過程:字符過濾器->字符處理->分詞過濾(分詞轉換)

說明:首先是字符過濾器過濾掉特殊符號以及量詞(the、an、a等),進一步將分詞小寫處理,服務器

英文分詞器(english analyzer)
  • 分析過程:字符過濾器->字符處理->分詞過濾(分詞轉換,詞幹轉化)

說明:首先是字符過濾器過濾掉特殊符號以及量詞(the、an、a等),進一步將分詞小寫處理,再次進行分詞轉換,例如:eating -> eat,其實它們兩是一回事。app

簡單分詞器(simple analyzer)

先按照空格分詞,英文大寫轉小寫。

空格分詞器(whitespace analyzer)

先按照空格分詞,英文不作大小寫處理。

二、外部分詞器

中文分詞器(ik_maxword)

會將文本作最細粒度的拆分;儘量多的拆分出詞語,例如:如南京市長江大橋 --> 南京市/南京/市長/長江大橋/長江/大橋

中文分詞器(ik_smart)

會作最粗粒度的拆分;已被分出的詞語將不會再次被其它詞語佔有,如南京市長江大橋 --> 南京市/長江大橋

安裝中文分詞器
  • 安裝方式一
#去GitHub下載與elasticsearch對應版本的分詞插件
https://github.com/medcl/elasticsearch-analysis-ik/releases

#進入es的plugins目錄建立文件夾
cd /usr/local/elasticsearch-7.8.0/plugins
mkdir analysis-ik

#解壓ik分詞插件到ik文件夾
unzip elasticsearch-analysis-ik-7.8.0.zip
  • 安裝方式二
cd /usr/local/elasticsearch-7.8.0/bin

#執行es自帶插件安裝命令
./elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.8.0/elasticsearch-analysis-ik-7.8.0.zip

說明:經過以上兩種方式之一安裝都可,安裝好插件重啓es服務便可。

十、評分規則

  • TF(token frequency):詞頻,文檔中出現分詞的數量,出現次數越多,相關性越強。
  • IDF(inverse document frequency):逆向文檔頻率,包含分詞的文檔數量相關,包含分詞的文檔數量越多則代表相關性越弱。
  • TFNORM(token frequency normalize):詞頻規格化,根據field長度作歸一化,文檔內出現頻率越高,field越短相關性越強。

2、基本語法

一、準備數據

抱着學習的目的,首先須要ElasticSearch的環境,有了環境之後,咱們還須要初始化一批數據,我們能夠藉助TMDB(the movie database)數據源來方便咱們練習基本語法。

二、建立索引

  • 非結構化方式建立索引
PUT /employee
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  }
}
  • 結構化方式建立索引
PUT /movie
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  },
  "mappings": {
    "properties": {
      "title":{"type": "text","analyzer": "english"},
      "tagline":{"type": "text","analyzer": "english"},
      "release_date":{"type": "date","format": "8yyyy/MM/dd||yyyy/M/dd||yyyy/MM/d||yyyy/M/d"},
      "popularity":{"type": "double"},
      "overview":{"type": "text","analyzer": "english"},
      "cast":{
        "type": "object",
        "properties": {
          "character":{"type":"text","analyzer":"standard"},
          "name":{"type":"text","analyzer":"standard"}
        }
      }
    }
  }
}

說明:以上指定了個別字段使用英文分詞器,日期類型指定了format,能夠支持解析多種類型的日期字符串格式。

三、刪除索引

  • 刪除索引
DELETE /employee

四、新增文檔

  • 強制指定建立,若已存在,則失敗
POST /employee/_create/1
{
  "name":"關二爺",
  "age":31
}
  • (不存在)新增或者(存在)更新文檔
PUT /employee/_doc/1
{
  "name":"jayway1",
  "age":30
}

說明:若是文檔不存在,則會插入文檔,若是文檔已存在,則會覆蓋原文檔。

五、修改文檔

  • 指定更新字段更新文檔
POST /employee/_update/1
{
  "doc": {
    "name":"jayway2"
  }
}

說明:指定字段更新就只會更新指定的字段,不會去覆蓋原文檔。

五、刪除文檔

  • 刪除指定文檔
DELETE /employee/_doc/1

六、簡單查詢文檔

  • 查詢指定文檔
GET /employee/_doc/2
  • 查詢多條文檔
GET /employee/_search
  • 不帶條件查詢全部記錄
GET /employee/_search
{
  "query": {
    "match_all": {}
  }
}
  • 分頁查詢
GET /employee/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 20
}
  • 帶關鍵字的條件查詢
GET /employee/_search
{
  "query": {
    "match": {
      "name": "關羽"
    }
  }
}
  • 帶關鍵字的條件查詢,並排序
GET /employee/_search
{
  "query": {
    "match": {
      "name": "關"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ]
}

說明:自主排序後,分數就沒有意義了,分數值爲null

  • 指定操做符查詢
#分詞後的and和or的邏輯,match默認使用的是or
GET /movie/_search
{
  "query": {
    "match": {
      "title": "basketball with cartoom aliens"
    }
  }
}

GET /movie/_search
{
  "query": {
    "match": {
      "title": {
        "query": "basketball with cartoom aliens",
        "operator": "and"
      }
    }
  }
}
  • 指定最小詞匹配項查詢
#最小詞匹配項(最小匹配兩個詞)
GET /movie/_search
{
  "query": {
    "match": {
      "title": {
        "query": "basketball love aliens",
        "operator": "or",
        "minimum_should_match": 2
      }
    }
  }
}
  • 短語查詢
#短語查詢,將查詢內容視做一個短語,不作分詞
GET /movie/_search
{
  "query": {
    "match_phrase": {
      "title": "steve zissou"
    }
  }
}
  • 多字段查詢
GET /movie/_search
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title","overview"]
    }
  }
}

說明:待查詢內容分詞分別匹配各個字段,每一個字段都有一個評分,取最大的評分。

  • 優化多字段查詢
#咱們認爲title字段比較重要,人爲地去幹涉評分的權重,
#以下的含義是:評分放大係數(boost,默認2.2)放大十倍
#tie_breaker:將除最大評分字段之外的其它字段得分乘以此係數累加到最大評分中得到最終得分;綜合考慮多個字段得分,而不是一刀切
GET /movie/_search
{
  "explain": true,
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^10","overview"],
      "tie_breaker": 0.3
    }
  }
}
  • 指定查詢類型的查詢
#best_fields(最匹配模式):默認的得分方式,取得最高的分數做爲對應文檔的對應分數
GET /movie/_search
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^10","overview"]
    }
  }
}

#most_fields:考慮絕大多數(全部的),文檔的字段得分相加,得到咱們想要的結果
GET /movie/_search
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^10","overview^0.1"],
      "type": "most_fields"
    }
  }
}

#cross_fields:以分詞爲單位計算欄位的總分,適用於詞維度的匹配,分詞在各個字段中的得分取最大值,而後累加這些最大得分
GET /movie/_search
{
  "query": {
    "multi_match": {
      "query": "steve job",
      "fields": ["title","overview"],
      "type": "cross_fields"
    }
  }
}
  • query string方式查詢
#方便的利用 and or not
GET /movie/_search
{
  "query": {
    "query_string": {
      "fields": ["title"],
      "query": "steve or jobs"
    }
  }
}

七、布爾查詢

  • 單條件過濾
GET /movie/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": {"title": "steve"}
      }
    }
  }
}

說明:term關鍵字查詢不會分詞,match纔會分詞

  • 多條件過濾
GET /movie/_search
{
  "query": {
    "bool": {
      "filter": [
        {"term":{"title": "steve"}},
        {"term":{"cast.name": "gaspard"}},
        {"range":{"release_date": {"lte":"2014/01/01"}}},
        {"range":{"popularity": {"gte":"25"}}}
      ]
    }
  }
}
  • 布爾查詢
#bool查詢
#must:必須都爲true
#must not:必須都是false
#should:其中只有一個爲true便可
#爲true越多則分數越高
GET /movie/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {"title": "basketball with cartoom aliens"}},
        {"match": {"overview": "basketball with cartoom aliens"}}
      ]
    }
  }
}
  • 帶match打分的filter
GET /movie/_search
{
  "query": {
    "bool": {
      "should": [
        {"match":{"title": "life"}}
      ], 
      "filter": [
        {"term":{"title": "steve"}},
        {"term":{"cast.name": "gaspard"}},
        {"range":{"release_date": {"lte":"2014/01/01"}}},
        {"range":{"popularity": {"gte":"25"}}}
      ]
    }
  }
}

說明:match查詢負責打分匹配,filter負責過濾,最終返回的文檔是有分數的。

  • 多條件過濾加排序
GET /movie/_search
{
  "query": {
    "bool": {
      "filter": [
        {"term":{"title": "steve"}},
        {"term":{"cast.name": "gaspard"}},
        {"range":{"release_date": {"lte":"2014/01/01"}}},
        {"range":{"popularity": {"gte":"25"}}}
      ]
    }
  },
  "sort": [
    {
      "popularity": {
        "order": "desc"
      }
    }
  ]
}

八、自定義得分查詢

  • 自定義得分查詢
#functionscore,對原始查詢獲得的分數,進一步進行處理
GET /movie/_search
{
  "query": {
    "function_score": {
      "query": {
        "multi_match": {
          "query": "steve job",
          "fields": ["title","overview"],
          "operator": "or",
          "type": "most_fields"
        }
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "popularity",
            "modifier": "log2p",
            "factor": 10
          }
        },
        {
          "field_value_factor": {
            "field": "popularity",
            "modifier": "log2p",
            "factor": 5
          }
        }
      ],
      "score_mode": "sum",
      "boost_mode": "sum"
    }
  }
}

九、聚合查詢

GET /employee/_search
{
  "query": {
    "match": {
      "name": "關"
    }
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ],
  "aggs": {
    "group_by_age": {
      "terms": {
        "field": "age",
        "size": 10
      }
    }
  }
}

九、查詢分析

  • 使用analyze api查看分詞狀態
GET /movie/_analyze
{
  "field": "name",
  "text": "Eating an apple a day & keeps the doctor away"
}
  • 使用explain查看打分的分析結果
GET /movie/_search
{
  "explain": true,
  "query": {
    "match": {
      "title": "steve"
    }
  }
}
  • explanation
GET /movie/_validate/query?explain
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^10","overview"],
      "type": "best_fields"
    }
  }
}
相關文章
相關標籤/搜索