ElasticSearch


ES

elasticsearch博客:https://www.cnblogs.com/Neeo/p/10864123.html#elk

 

  E: elastic

  S: search

Lucene

Lucene可以被認為是迄今為止最先進、性能最好的、功能最全的搜索引擎庫。

基於Lucene的搜索引擎,Java開發,包括:

  • Lucene
  • Solr
  • elasticsearch
  • katta
  • compass

 

ElasticSearch

ElasticSearch是一個基於Lucene的搜索服務器。它提供了一個分布式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java開發的,並作為Apache許可條款下的開放源碼發布,是當前流行的企業級搜索引擎。設計用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便。

 

elasticsearch中,是以文檔的形式存儲數據。

文檔要比數據表的行更加靈活。因為文檔可以是多層次的,它(文檔)鼓勵你將屬於一個邏輯實體的數據保存在同一個文檔中,而不是散落在各個表的不同行中。這樣查詢效率很高,因為我們無需連接其他的表


優點:

  • 分布式:節點對外表現對等,加入節點自動均衡
  • elasticsearch完全支持Apache Lucene的接近實時的搜索
  • 各節點組成對等的網絡結構,當某個節點出現故障時會自動分配其他節點代替期進行工作
  • 橫向可擴展性,如果你需要增加一台服務器,只需要做點配置,然后啟動就完事了
  • 高可用:提供復制(replica)機制,一個分片可以設置多個復制,使得某台服務器宕機的情況下,集群仍舊可以照常運行,並會把由於服務器宕機丟失的復制恢復到其它可用節點上;這點也類似於HDFS的復制機制(HDFS中默認是3份復制)

缺點:

    • 不支持事物
    • 相對吃內存

 

 

前言

  • 邏輯設計,我們可以把elasticsearch與關系型數據做個客觀對比:
Relational DB Elasticsearch
數據庫(database) 索引(indices)
表(tables) types
行(rows) documents
字段(columns) fields

  elasticsearch(集群)中可以包含多個索引(數據庫),每個索引中可以包含多個類型(表),每個類型下又包含多個文檔(行),每個文檔中又包含多個字段(列)。

  • 物理設計

  注意:當然,這里需要補充的是,從elasticsearch的第一個版本開始,每個文檔都存儲在一個索引中,並分配多個映射類型,映射類型用於表示被索引的文檔或者實體的類型,但這也帶來了一些問題(詳情參見Removal of mapping types),導致后來在elasticsearch6.0.0版本中一個文檔只能包含一個映射類型,而在7.0.0中,映射類型則將被棄用,到了8.0.0中則將完全被刪除。

 

 

 

邏輯設計:文檔、類型、索引

一個索引類型中,包含多個文檔,比如說文檔1,文檔2。
當我們索引一篇文檔時,可以通過這樣的順序找到它:索引類型文檔ID,通過這個組合我們就能索引到某個具體的文檔。
注意:ID不必是整數,實際上它是個字符串。

文檔

elasticsearch是面向文檔的,那么就意味着索引和搜索數據的最小單位是文檔,elasticsearch中,文檔有幾個重要屬性:

  • 自我包含,一篇文檔同時包含字段和對應的值,也就是同時包含key:value
  • 可以是層次型的,一個文檔中包含自文檔,復雜的邏輯實體就是這么來的
  • 靈活的結構,文檔不依賴預先定義的模式,我們知道關系型數據庫中,要提前定義字段才能使用,在elasticsearch中,對於字段是非常靈活的,有時候,我們可以忽略該字段,或者動態的添加一個新的字段。
  • 文檔是無模式的,也就是說,字段對應值的類型可以是不限類型的。

盡管我們可以隨意的新增或者忽略某個字段,但是,每個字段的類型非常重要,比如一個年齡字段類型,可以是字符串也可以是整型。因為elasticsearch會保存字段和類型之間的映射及其他的設置。這種映射具體到每個映射的每種類型(因此帶來的問題),這也是為什么在elasticsearch中,類型有時候也稱為映射類型。

類型

類型是文檔的邏輯容器,就像關系型數據庫一樣,表格是行的容器。
類型中對於字段的定義稱為映射,比如name映射為字符串類型。
我們說文檔是無模式的,它們不需要擁有映射中所定義的所有字段,比如新增一個字段,那么elasticsearch是怎么做的呢?elasticsearch會自動的將新字段加入映射,但是這個字段的不確定它是什么類型,elasticsearch就開始猜,如果這個值是18,那么elasticsearch會認為它是整型。
但是elasticsearch也可能猜不對,所以最安全的方式就是提前定義好所需要的映射,這點跟關系型數據庫殊途同歸了,先定義好字段,然后再使用,別整什么幺蛾子。后面在討論更多關於映射的東西。

索引

索引是映射類型的容器,elasticsearch中的索引是一個非常大的文檔集合。索引存儲了映射類型的字段和其他設置。然后它們被存儲到了各個分片上了。
我們來研究下分片是如何工作的。

 

物理設計:節點、分片

一個集群包含至少一個節點,而一個節點就是一個elasticsearch進程。節點內可以有多個索引。
默認的,如果你創建一個索引,那么這個索引將會有5個分片(primary shard,又稱主分片)構成,而每個分片又有一個副本(replica shard,又稱復制分片),這樣,就有了10個分片。

那么這個索引是如何存儲在集群中的呢?

 

 主分片和對應的復制分片都不會在同一個節點內,這樣有利於某個節點掛掉了,數據也不至於丟失。
實際上,一個分片是一個Lucene索引,一個包含倒排索引的文件目錄,倒排索引的結構使得elasticsearch在不掃描全部文檔的情況下,就能告訴你哪些文檔包含特定的關鍵字。

倒排索引

elasticsearch使用的是一種稱為倒排索引的結構,采用Lucene倒排索作為底層。這種結構適用於快速的全文搜索,一個索引由文檔中所有不重復的列表構成,對於每一個詞,都有一個包含它的文檔列表。
倒排列表(Posting List)記錄了詞條對應的文檔集合,由倒排索引項(Posting)組成。

倒排索引項主要包含如下信息:

  • 文檔id,用於獲取原始信息。
  • 詞條頻率(TF,Term Frequency),記錄該詞條在文檔中出現的次數,用於后續相關性算分。
  • 位置(Position),記錄詞條在文檔中的分詞位置(多個),用於做短語搜索(Phrase Query)。
  • 偏移(Offset),記錄詞條在文檔的開始和結束位置,用於做高亮顯示。

搜索引擎為例:

 

文檔id 文檔內容
1 elasticsearch是最流行的搜索引擎
2 Python是世界上最好的語言
3 搜索引擎是如何誕生的

上述文檔的倒排索引列表是這樣的:

DocID TF Position Offset
1 1 2 <18,22>
3 1 0 <0,4>

關於文檔1,DocID是1無需多說,TF是1表示搜索引擎在文檔內容中出現一次,Position指的是分詞后的位置,首先要說文檔內容會被分為elasticsearch最流行搜索引擎3部分,從0開始計算,搜索引擎Position是2;Offset搜索引擎這個字符在文檔中的位置。

文檔3中搜索引擎在文檔中出現一次(TF:1),並且出現在文檔的開始位置(Position:0),那么Offset的位置就是<0,4>無疑了。

再比如說,現在有兩個文檔, 每個文檔包含如下內容:

Study every day, good good up to forever # 文檔1包含的內容 To forever, study every day, good good up # 文檔2包含的內容

為了創建倒排索引,我們首先要將每個文檔拆分成獨立的詞(或稱為詞條或者tokens),然后創建一個包含所有不重復的詞條的排序列表,然后列出每個詞條出現在哪個文檔:

term doc_1 doc_2
Study ×
To ×
every
forever
day
study ×
good
every
to ×
up

現在,我們試圖搜索to forever,只需要查看包含每個詞條的文檔:

term doc_1 doc_2
to ×
forever
total 2 1

兩個文檔都匹配,但是第一個文檔比第二個匹配程度更高。如果沒有別的條件,現在,這兩個包含關鍵字的文檔都將返回。

再來看一個示例,比如我們通過博客標簽來搜索博客文章。那么倒排索引列表就是這樣的一個結構:

如果要搜索含有python標簽的文章,那相對於查找所有原始數據而言,查找倒排索引后的數據將會快的多。只需要查看標簽這一欄,然后獲取相關的文章ID即可。

elasticsearch的索引和Lucene的索引對比

在elasticsearch中,索引這個詞被頻繁使用,這就是術語的使用。
並且elasticsearch將索引被分為多個分片,每份分片是一個Lucene的索引。所以一個elasticsearch索引是由多個Lucene索引組成的。

環境配置

elasticsearch for windows:Java環境配置

java

jdk安裝一路下一步
配置JAVA_HOME 在系統變量里面新建一個變量名:JAVA_HOME,變量值:C:\Program Files\Java\jdk1.8.0_201
配置Path : 在系統變量的Path中,追加 %JAVA_HOME%\bin;

elasticsearch

 elasticsearch下載安裝

解壓到合適的目錄中,合適:路徑不要有中文 空格 特殊字符
啟動安裝目錄中的bin目錄下的 elasticsearch.bat
瀏覽器訪問: http://127.0.0.1:9200/ --> json字符串 說明安裝成功

kibana

 kibana for windows

解壓到合適的目錄中,合適:路徑不要有中文 空格 特殊字符
啟動安裝目錄中的bin目錄下的 kibana.bat
瀏覽器訪問: http://127.0.0.1:5601/ --> web頁面
dev tools --> console

 

增刪改查

創建文檔

PUT zrq/doc/1
{
  "name":"nihao"
}

返回

{
  "_index" : "zrq",
  "_type" : "doc",
  "_id" : "1",
  "_version" : 3,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

 

結果中的result則是操作類型,現在是created,表示第一次創建。如果我們再次點擊執行該命令,那么result則會是updated。我們細心則會發現_version開始是1,現在你每點擊一次就會增加一次。表示第幾次更改。

查詢所有索引

GET _cat/indices?v

展示當前集群中索引情況,包括,索引的健康狀況、UUID、主副分片個數、大小等信息。

查詢指定的索引信息

GET zrq/doc/_search

返回

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "zrq",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "shuai"
        }
      },
      {
        "_index" : "zrq",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "nihao"
        }
      }
    ]
  }
}

查詢文檔信息

GET zrq/doc/1

刪除所有

后追加文件

DELETE zrq

 

刪除指定索引

DELETE zrq/doc/1

指定替換

POST zrq/doc/2/_update
{
  "doc": {
    "age":[19]
  }
}

全部替換

PUT全部替換

PUT zrq/doc/2
{
  pass  
}

 

查詢的兩種方式

字符串查詢

GET zhifou/doc/_search?q=from:gu

還是使用GET命令,通過_serarch查詢,查詢條件是什么呢?條件是from屬性是gu家的人都有哪些。最后,別忘了_searchfrom屬性中間的英文分隔符?

 

結構化查詢

使用DSL方式

GET zhifou/doc/_search
{
  "query": {
    "match": {
      "from": "gu"
    }
  }
}
query條件
match 和 match_all

上例,查詢條件是一步步構建出來的,將查詢條件添加到match中即可,而match則是查詢所有from字段的值中含有gu的結果就會返回。

sort

升降序 desc和asc

GET zrq/doc/_search
{
  "query":{
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "asc"
      }
    }
  ]
}

 

from

from   索引位置

size   拿取數量

GET zrq/doc/_search
{
  "query":{
    "match_all": {}
  },
  "from":0,
  "size":2
}

_source選擇字段
可以為下面兩種方式
"_source": "{name}"
"_source": ["name","age"]
GET zrq/doc/_search
{
  "query":{
    "match_all": {}
  },
  "from":0,
  "size":2,"_source": "{name}"
}

 

 

 

elasticsearch之match系列

 

高亮查詢

 

elasticsearch之布爾查詢

 

elasticsearch之聚合函數

 

elasticsearch之mappings

 

elasticsearch mappings之dynamic的三種狀態

 

elasticsearch之mappings的其他設置:index、copy_to、對象屬性、settings

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

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



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