〈二〉ElasticSearch的認識:索引、類型、文檔

来源:https://www.cnblogs.com/progor/archive/2019/09/19/11548269.html
-Advertisement-
Play Games

[toc] 發表日期:2019年9月19日 上節回顧 在學習新的內容之前,先回顧一下上節的內容,上節主要講述了以下的內容: 1. ElasticSearch是什麼?什麼是搜索引擎?為什麼選擇ElasticSearch? 2. 搜索是怎麼做到的:分詞、倒排索引? 3. 環境的搭建 4. 如何通過kib ...


目錄

發表日期:2019年9月19日


上節回顧

在學習新的內容之前,先回顧一下上節的內容,上節主要講述了以下的內容:

  1. ElasticSearch是什麼?什麼是搜索引擎?為什麼選擇ElasticSearch?
  2. 搜索是怎麼做到的:分詞、倒排索引?
  3. 環境的搭建
  4. 如何通過kibana操作elasticsearch
  5. hello world中講述瞭如何使用“寫數據->查指定數據”,"寫數據->通過關鍵字搜索數據"

本節前言

這節將涉及index、type、document的增刪查改相關的內容。
index就像sql中的庫,type就像sql中的表,document就像sql中的記錄。
這節認識index,type,document,會幫助我們認識ElasticSearch數據存儲的邏輯結構。就好像你學SQL要先學會了建庫、建表,才能插入記錄。而一些更深一點的內容,例如如何對document進行搜索、排序,這些將留到下一節再講。


索引index

索引index是存儲document文檔數據的結構,意義類似於關係型資料庫中的資料庫。




創建索引

在上一節的hello world中,我們並沒有講如何創建索引,那裡直接就插入了數據,那樣的話ElasticSearch會幫我們以預設的配置來自動創建索引。
下麵講一下如何手動創建索引:

語法:

// 語法:
PUT /索引名
{
    index的配置(primary shard的數量等)
}

例子:

// 例子(不帶配置信息的話以預設配置創建)【請不要複製這個註釋!】:
PUT /product

// 例子(帶配置信息的話以配置信息創建)【請不要複製這個註釋!】
PUT /product
{
    "settings":{
        "index":{
            "number_of_shards":3,
            "number_of_replicas":1
          }
     }
}

在上述的例子中:number_of_shards是主分片的數量;number_of_replicas是副本分片的數量(這裡提一下,number_of_replicas副本分片的數量是面向主分片的,所以這個值為1時代表每一個主分片有一個副本分片)。

返回結果:

{
  "acknowledged": true,
  "shards_acknowledged": true,
  "index": "product"
}

【在插入一個文檔的時候,如果index還沒有創建,那麼會自動創建,這時候index的一些配置會採用預設的配置,預設的主分片數量是5,副本分片數量是1




查看索引

查看單個索引

語法:GET /索引名
效果:返回指定索引的信息
例子:GET /product
返回結果解析:

  • aliases:是索引的別名,由於我們沒有定義索引別名所以沒有數據(索引別名後面再講)
  • mappings:是索引中存儲的數據的結構信息,由於上圖的索引product中並沒有存儲document,而且我們也沒有指定,所以也為空。mappings定義了文檔的欄位的數據類型和搜索策略等信息。【後面的知識點】
  • settings:索引的配置信息
    • creation_date是創建日期(毫秒級別的時間戳)
    • number_of_shards是主分片數量
    • number_of_replicas是副本分片的數量
    • uuid是索引的id
    • version是索引的版本信息
    • provided_name是索引名
      一個包含了mappings的結果圖:




查看所有索引

命令:GET /_cat/indices?v
效果:查看所有索引,顯示索引的健康狀態等信息。
【如果沒有v選項,那麼就不會有第一行關於該列意義的頭部】
返回結果解析:

  • health: 索引的健康狀態(受分片的運行狀態影響)【集群管理的知識點】
  • status: 索引是開啟的還是關閉的
  • index: index的名稱
  • uuid:索引的UUID
  • pri: primary shared的數量
  • rep: replicated shared的數量
  • docs.count: 文檔document的數量
  • docs.deleted: 被刪除的文檔document的數量
  • store.size:總數據的大小
  • pri.store.size:主分片上的數據的大小(這裡因為只運行了一個服務節點,所以沒有可運行的副本分片,所以總數據大小等於主分片的數據大小)




刪除索引

語法:DELETE /索引名【支持同時刪除多個索引,以逗號分割,如DELETE /testindex1,testindex2】
語法例子:DELETE /product
返回結果:【當acknowledged為true的時候代表刪除成功】

{
  "acknowledged": true
}




修改索引

【修改索引主要是修改分片數量、mapping、分詞器,由於mapping和分詞器涉及很深,需要前置知識,所以留到後面講。】

修改副本分片數量

不講語法了,直接看例子:

PUT /product/_settings
{
  "index":{
    "number_of_replicas":2
  }
}




關閉索引

關閉索引是為了避免修改索引的配置時他人進行文檔讀寫。關閉索引後,就只能獲取索引的配置信息,而不能讀寫索引中的document。有時候也用於關閉一些無用的索引來減少資源消耗。
語法:

  • 關閉索引:POST /索引名/_close
  • 打開索引:POST /索引名/_open




索引別名

索引別名是一個“別名”,但能夠像索引名那樣使用,它的使用場景一方面是“使用更簡潔的索引名來獲取數據”,另一個方面是“通過索引別名來指向索引(別名B指向索引A),方便修改指向的索引,用於解決可能的更換索引的場景(比如你需要統一修改原有索引的信息,那你可以新建索引C,C存儲了修改後的數據,更改指向原本索引A的索引別名B指向C)。”

增加索引別名:

語法:

POST /_aliases
{
    "actions":[
        {
            "add":{
                "index":"索引名",
                "alias":"索引別名"
            }
        }
    ]
}

例子:

POST /_aliases
{
  "actions":[
    {
      "add":{
        "index":"product",
        "alias":"pdt"
      }
    }
    ]
}

查看索引別名:

  • 方法一:通過查看索引來查看索引別名:GET /product
  • 方式二:通過命令GET /product/_alias
  • 【索引別名有了就會生效,不信你在GET /product的時候直接用上別名】

刪除索引別名:

語法:

POST /_aliases
{
    "actions":[
        {
            "remove":{
                "index":"索引名",
                "alias":"索引別名"
            }
        }
    ]
}

例子:

POST /_aliases
{
  "actions":[
    {
      "remove":{
        "index":"product",
        "alias":"pdt"
      }
    }
    ]
}

【你應該看到了,actions裡面是一個數組,所以你是可以同時進行多個操作的。】




補充

  • 有很多關於index的配置。由於也是一個比較大的知識點(需要一些前置知識,單獨在這裡講的話會很空白),將會單獨列出來。
  • index有個mapping配置,mapping定義整體的index的document的結構,和影響分詞策略。由於會影響搜索,所以把這個歸為搜索的分支知識點,將留到搜索篇再談。

小節總結:

本小節講瞭如何創建索引,如何查看索引、如何刪除索引、如何修改索引(修改副本分片數量)、如何關閉/開啟索引、如何定義索引別名。
目的在於介紹如何創建存儲document的邏輯結構--索引,雖然我們有時候是不需要手動顯示創建索引的,但手動創建是個必須瞭解的知識,因為mapping和分詞器有時候需要手動來指定。


類型type

類型type也是用於存儲document的邏輯結構,相對於index來說,type是index的下級,所以通常在面向有實際意義的數據時,index作為大類的劃分,type作為小類的劃分。比如如果把book書作為一個大類來建立index的話,那麼書的類型(小說類、文學類、IT技術類等)就可以作為type。


你可能以為下麵要講如何CRUD類型type了吧。但其實這裡並不需要講這些,因為type其實並不真的用來劃分邏輯結構,它只是意義上的!ElasticSearch使用了Lucene的底層架構,而Lucene是沒有type。


上面說了,index就像sql中的庫,type就像sql中的表,document就像sql中的記錄。
但事實上,ElasticSearch“真正用於分隔數據的結構“只有index,而沒有type,type實際上作為了一個元數據(類似SQL中的id,作為額外的標識數據)來實現邏輯劃分。【如果你不懂的話,可以從SQL方面想,就好像一個職員表,一條記錄中的某一個欄位說明瞭他屬於哪個部門】。當然了,這是一些偏原理的內容了。這些都將留到原理篇來闡述。這裡僅僅是淺嘗即止。
不過由於沒有type沒有真實地用於分隔數據,所以要註意結構類型偏差太大的數據還是不要放在一個index好。


之前說了,index用來劃分大類,type用來劃分小類。而可能有些人會把這個大類定的過大,比如電影和書籍這兩個小類(type)的數據大多是不一樣的,但他們都可以屬於娛樂這一個大類(index),由於type並沒有真實地用於分隔數據地用於存儲數據,所以數據存儲的時候針對的還是index。

ElaticSearch並不是完全無結構的,不要與某些NoSQL資料庫混為一談,雖然它的結構非常靈活(面向json,可以隨意增加欄位)。在index中還有一個mapping,mapping管理了整個index的各個欄位的屬性,也就是定義了整個index中document的結構。我們在index下不同type中定義的document的欄位都會在mapping中。所以說,如果你定義的多個type的結構偏差太大,那麼會導致mapping需要存儲的欄位的數據過多,同時也影響index的物理存儲結構,因為index會按照mapping來存儲數據。【換到SQL中的話,也就是比如你有一個商品表,商品表下麵有各種商品(書籍、食物),而它們的數據是很不一樣的,比如書籍有出版日期,食物有保質期,如果把它們都放到一個表中的話,那麼就會導致這個表的欄位過多。】


如何測試document文檔的數據結構是面向index?【這個測試你可以不做,現在僅僅記住上面的知識點,測試後面再做,因為這個涉及到一些後面的知識】
1.定義一個document的一個欄位為date類型;然後在另一個type中添加為text類型的同名欄位。
當我們直接插入document的時候,如果不指定document的數據結構,那麼ElastciSearch會基於dynamic mapping來自動幫我們聲明每一個欄位的數據類型,比如"content":"hello world!"會被聲明成字元串類型,"post_date":"2017-07-07"會被認為是date類型。如果我們首先在一個type中聲明瞭content為字元串類型,再在另外一個type中聲明成日期類型,這會報錯,因為對於index來說,這個content已經被聲明成字元串類型了。

2.查看mapping:
在查看mapping的時候,我們是通過查看索引來查看的,其實也反向證明瞭mapping是面向index的。


補充:

  • 上面說了index的mapping會存儲完整的多個type的欄位信息,如果type的欄位差別太大,那麼就會導致mapping需要存儲的欄位過多。ElasticSearch維護組織後面發現這多個type的情況確實有點煩人。於是他們準備讓一個index只放一個type了,在6.x版本中,一個索引下只有一個type,如果聲明多個type,會被標記為過期,但是仍可以使用。7.0之後的版本將完全移除ElasticSearch移除多個type

小節總結:

  • 本節重新解釋了type的意義,type實際上是作為document中的一個固定欄位存在的,文檔的數據結構是面向index的,所以不能把欄位差異性較大的數據存儲在一個index中。

文檔document

文檔的格式是json式的。
對於文檔,有幾個主要的標識信息:_index(插入到哪個索引中),_type(插入到哪個類型中),_id(文檔的id是多少),在插入一個文檔的時候,這幾個信息也是必須的。

  • 在考慮web開發的大多都知道json的基本格式,所以我這裡只會編寫一個簡單的json數據作為例子,json數據裡面的數據類型問題留到後面再進行補充。

插入文檔

語法:

PUT /index/type/id
json格式的數據

例子:

PUT /douban/book/4
{
    "book_id":4,
    "book_name":"Other Voices, Other Rooms",
    "book_author":"Truman Capote",
    "book_pages":240,
    "book_express":"Vintage",
    "publish_date":"1994-02-01",
    "book_summary":"""
  Truman Capote’s first novel is a story of almost supernatural intensity and inventiveness, an audacious foray into the mind of a sensitive boy as he seeks out the grown-up enigmas of love and death in the ghostly landscape of the deep South.
  
  At the age of twelve, Joel Knox is summoned to meet the father who abandoned him at birth. But when Joel arrives at the decaying mansion in Skully’s Landing, his father is nowhere in sight. What he finds instead is a sullen stepmother who delights in killing birds; an uncle with the face—and heart—of a debauched child; and a fearsome little girl named Idabel who may offer him the closest thing he has ever known to love."""
}

結果解析:

  • _index:插入到哪個index中。
  • _type:插入到哪個type中。
  • _id:插入的文檔的id是多少。
  • _version:版本,對這個ID的文檔的操作次數
  • result:操作結果,第一次操作時created,上圖中因為我忘記截圖了,所以重新插入了一次,所以時updated
  • _shards:
    • total:總共有多少個shard
    • successful:成功多少個,【由於寫操作只會發生在primary shard中,所以這裡為1,另一個shard時replica shard,不發生寫操作】
    • failed:失敗多少個




查詢指定文檔

語法:

GET /index/type/id

例子:

GET /douban/book/1

結果解析:




更新文檔

語法:

// 全替換(覆蓋)式更新:會使用新的json數據直接覆蓋原有的【請不要複製註釋】
PUT /index/type/id
json數據

// 部分替換式更新:只會覆蓋指定數據
POST /index/type/id/_update
{
  "doc": {
    "需要修改的欄位": "修改值"
    [,"需要修改的欄位": "修改值"]
  }
}

例子:

【全替換語句與插入差不多,所以不舉例了】

POST /douban/book/4/_update
{
  "doc": {
    "book_pages":241,
    "publish_date":"1994-02-02"
  }
}

結果解析:
返回結果與插入時大概一致,不同的時result變成了updated




刪除文檔

語法:

DELETE /index/type/id

例子:
【刪除後可以重新執行插入語句恢複數據】

DELETE /douban/book/4

結果解析:
返回結果與插入時大概一致,不同的時result變成了deleted.




查詢所有文檔

語法:

GET /index/type/_search

GET /index/type/_search
{
  "query":{
    "match_all": {}
  }
}

例子:

GET /douban/book/_search

GET /douban/book/_search
{
  "query":{
    "match_all": {}
  }
}




補充:

上面介紹了關於文檔的CRUD基操,但還有很多東西沒講,這些將留到後面講,包括:文檔的欄位的數據類型、文檔的搜索、文檔的元數據(_index,_type,_id等)




小節總結

這節講瞭如何對文檔進行CRUD操作,PUT用於插入,GET用於查詢,PUT和POST用於修改,DELETE用於刪除。






您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 記錄工作中遇到的問題,分享出來: 原博客地址:https://blog.csdn.net/weixin_40782680/article/details/85038281 今天遇到一個比較鬱悶的問題,如下圖: 點擊庫存或者點擊銷售,查詢數據很慢,有的將近幾十秒,查詢數據用的是存儲過程,在資料庫中執行 ...
  • sqlserver存儲過程入門 1. 輸入/輸出參數定義 @object_name varchar(50) //定義一個varchar類型的輸入參數 @object_index int @isUpdate int =0 output //定義一個輸出參數 2.游標使用步驟 1、定義游標 DECLAR ...
  • Windows下Redis安裝配置和使用註意事項 一:下載 下載地址: https://github.com/microsoftarchive/redis/releases 文件介紹: 本文以3.2.100為例 Redis-x64-3.2.100.msi是在windows下,最簡單的安裝文件,方便, ...
  • Redis 事務 == [toc] Redis操作時支持事務的。事務具有原子性atomic,包含在事務中的操作要麼都執行成功,要麼都執行失敗。但是redis不支持回滾,但是可以在測試開發環節避免錯誤操作。可以說原子性上是半支持的,看後面原因。 很多時候我們需要進行事務操作。 翻譯官檔:https:/ ...
  • 本來這一節想寫Hadoop的分散式高可用環境的搭建,寫到一半,發現還是有必要先介紹一下ZooKeeper這個東西。 ZooKeeper理念介紹 ZooKeeper是為分散式應用來提供協同服務的,而且ZooKeeper本身也是分散式的,由分佈在至少三台機器上,這幾台機器形成一個Quorum,就像一個劇 ...
  • 一 庫操作 1、創建資料庫 1.1 語法 CREATE DATABASE 資料庫名 charset utf8; 1.2 資料庫命名規則 可以由字母、數字、下劃線、@、#、$ 區分大小寫 唯一性 不能使用關鍵字如 create select 不能單獨使用數字 最長128位 基本上跟python或者js ...
  • https://www.jb51.net/article/52269.htm註:本文譯自《Oracle Data Guard 11g Handbook》 Page 78 – Page 88這篇文章主要介紹了Oracle 11g Dataguard參數詳解,包含了獨立參數、主庫參數、備庫參數的詳細說明 ...
  • 一、 Redis 介紹 Remote Dictionary Server(Redis)是一個開源的使用 ANSI C 語言編寫、支持網路、可基於記憶體亦可持久化的日誌型、Key-Value 資料庫,並提供多種語言的 API。它通常被稱為數據結構伺服器,因為值(value)可以是 字元串(String) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...