1. 程式人生 > 實用技巧 >自然語言處理4-3:語言模型之n-gram模型

自然語言處理4-3:語言模型之n-gram模型

1. 簡介

1.1 歷史

以下內容來自百度百科:https://baike.baidu.com/item/elasticsearch/3411206?fr=aladdin

Shay Banon在2004年創造了Elasticsearch的前身,稱為Compass。在考慮Compass的第三個版本時,他意識到有必要重寫Compass的大部分內容,以“建立一個可擴充套件的搜尋解決方案”。因此,他建立了“一個從頭構建的分散式解決方案”,並使用了一個公共介面,即HTTP上的JSON,它也適用於Java以外的程式語言。Shay Banon在2010年2月釋出了Elasticsearch的第一個版本。

Elasticsearch BV成立於2012年,主要圍繞Elasticsearch及相關軟體提供商業服務和產品。2014年6月,在成立公司18個月後,該公司宣佈通過C輪融資籌集7000萬美元。這輪融資由新企業協會(NEA)牽頭。其他投資者包括Benchmark Capital和Index Ventures。這一輪融資總計1.04億美元

2015年3月,Elasticsearch公司更名為Elastic。

在2018年6月,Elastic提交了首次公開募股申請,估值在15億到30億美元之間。公司於2018年10月5日在紐約證券交易所掛牌上市。一些組織將Elasticsearch作為託管服務提供。這些託管服務提供託管、部署、備份和其他支援。大多數託管服務還包括對Kibana的支援。

Elasticsearch 自從誕生以來,其的應用越來越廣泛,特別是大資料領域,功能也越來越強大,但是如何有效的監控管理 Elasticsearch 一直是公司所面對的難題,由於 Elasticsearch 叢集的穩定性,決定了其業務發展的高度,對於一個應用來說其穩定是第一目標,所以完善的監控體系是必不可少的。此外,Elasticsearch 寫入和查詢對資源的消耗都很大,如何合理有效地控制資源,既能滿足寫入和查詢的需求,又能滿足資源充分利用,這是公司必須面對的問題。

在國內,還沒較為完善的面向 Elasticsearch 的監控管理平臺,很多企業往往只關注搭建一套簡單分散式的叢集環境,而對這個叢集的缺乏監控和管理,元資料混亂,寫入和查詢耦合,缺乏監控一旦叢集出現問題,就會導致資料丟失,甚至很容易導致線上應用故障。相比於小公司,中大型公司的資金較為充足,所以中大型公司,會選擇為每個應用去維護一套叢集,但是這每當資源不夠需要擴容或者縮容時,極其不方便,需要增加刪除節點,其運維成本過高。而且對每個應用來說,可能不能夠充分利用資源,但是如果和其他應用混合部署,但是又涉及到複雜的資源分配問題,而且隨著應用的發展,資源經常需要變動。在國外,ELasticsearch 的應用也很廣泛,也有對 Elasticsearch 進行很好的監控和管理,Amazon AWS

中也有基於 Elasticsearch 構建的平臺服務,幫助電商應用程式,網站等提供安全,高可靠,低成本,低延時,高吞吐的量的個性化搜尋。雖然,對叢集進行了監控和管理,但是管理的維度還是叢集級別的,而對於應用往往是模板級別的,如果應用無法和叢集一一對應,那就無法進行更高效的管理。這無法滿足公司級別想要高效利用資源,叢集內部能支援多個應用的場景

1.2 ElasticSearch 概述

Elasticsearch是一個開源的分散式、RESTful 風格的搜尋和資料分析引擎,它的底層是開源庫Apache Lucene。
 Lucene 可以說是當下最先進、高效能、全功能的搜尋引擎庫——無論是開源還是私有,但它也僅僅只是一個庫。為了充分發揮其功能,你需要使用 Java 並將 Lucene 直接整合到應用程式中。 更糟糕的是,您可能需要獲得資訊檢索學位才能瞭解其工作原理,因為Lucene 非常複雜。
 為了解決Lucene使用時的繁複性,於是Elasticsearch便應運而生。它使用 Java 編寫,內部採用 Lucene 做索引與搜尋,但是它的目標是使全文檢索變得更簡單,簡單來說,就是對Lucene 做了一層封裝,它提供了一套簡單一致的 RESTful API 來幫助我們實現儲存和檢索。
 當然,Elasticsearch 不僅僅是 Lucene,並且也不僅僅只是一個全文搜尋引擎。 它可以被下面這樣準確地形容:

  • 一個分散式的實時文件儲存,每個欄位可以被索引與搜尋;
  • 一個分散式實時分析搜尋引擎;
  • 能勝任上百個服務節點的擴充套件,並支援 PB (大資料)級別的結構化或者非結構化資料。
    由於Elasticsearch的功能強大和使用簡單,維基百科、衛報、Stack Overflow、GitHub等都紛紛採用它來做搜尋。現在,Elasticsearch已成為全文搜尋領域的主流軟體之一。

1.3 ElasticSearch和solr的差別

1.3.1 Elasticsearch簡介

Elasticsearch是一個實時分散式搜尋和分析引擎。它讓你以前所未有的速度處理大資料成為可能。
它用於全文搜尋、結構化搜尋、分析以及將這三者混合使用:
維基百科使用Elasticsearch提供全文搜尋並高亮關鍵字,以及輸入實時搜尋(search-asyou-type)和搜尋糾錯(did-you-mean)等搜尋建議功能。
英國衛報使用Elasticsearch結合使用者日誌和社交網路資料提供給他們的編輯以實時的反饋,以便及時瞭解公眾對新發表的文章的迴應。
StackOverflow結合全文搜尋與地理位置查詢,以及more-like-this功能來找到相關的問題和答案。
Github使用Elasticsearch檢索1300億行的程式碼。
但是Elasticsearch不僅用於大型企業,它還讓像DataDog以及Klout這樣的創業公司將最初的想法變成可擴充套件的解決方案。Elasticsearch可以在你的筆記本上執行,也可以在數以百計的伺服器上處理PB級別的資料 。

Elasticsearch是一個基於Apache Lucene(TM)的開源搜尋引擎。無論在開源還是專有領域,Lucene可以被認為是迄今為止最先進、效能最好的、功能最全的搜尋引擎庫。
但是,Lucene只是一個庫。想要使用它,你必須使用Java來作為開發語言並將其直接整合到你的應用中,更糟糕的是,Lucene非常複雜,你需要深入瞭解檢索的相關知識來理解它是如何工作的。
Elasticsearch也使用Java開發並使用Lucene作為其核心來實現所有索引和搜尋的功能,但是它的目的是通過簡單的 RESTful API 來隱藏Lucene的複雜性,從而讓全文搜尋變得簡單。

1.3.2Solr簡介

Solr 是Apache下的一個頂級開源專案,採用Java開發,它是基於Lucene的全文搜尋伺服器。Solr提供了比Lucene更為豐富的查詢語言,同時實現了可配置、可擴充套件,並對索引、搜尋效能進行了優化

Solr可以獨立執行,執行在Jetty、Tomcat等這些Servlet容器中,Solr 索引的實現方法很簡單,用 POST 方法向 Solr 伺服器傳送一個描述 Field 及其內容的 XML 文件,Solr根據xml文件新增、刪除、更新索引 。Solr 搜尋只需要傳送 HTTP GET 請求,然後對 Solr 返回Xml、json等格式的查詢結果進行解析,組織頁面佈局。Solr不提供構建UI的功能,Solr提供了一個管理介面,通過管理介面可以查詢Solr的配置和執行情況。

solr是基於lucene開發企業級搜尋伺服器,實際上就是封裝了lucene。

Solr是一個獨立的企業級搜尋應用伺服器,它對外提供類似於Web-service的API介面。使用者可以通過http請求,向搜尋引擎伺服器提交一定格式的檔案,生成索引;也可以通過提出查詢請求,並得到返回結果。

1.3.3Lucene簡介

Lucene是apache軟體基金會4 jakarta專案組的一個子專案,是一個開放原始碼的全文檢索引擎工具包,但它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,提供了完整的查詢引擎和索引引擎,部分文字分析引擎(英文與德文兩種西方語言)。Lucene的目的是為軟體開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎。Lucene是一套用於全文檢索和搜尋的開源程式庫,由Apache軟體基金會支援和提供。Lucene提供了一個簡單卻強大的應用程式介面,能夠做全文索引和搜尋。在Java開發環境裡Lucene是一個成熟的免費開源工具。就其本身而言,Lucene是當前以及最近幾年最受歡迎的免費Java資訊檢索程式庫。人們經常提到資訊檢索程式庫,雖然與搜尋引擎有關,但不應該將資訊檢索程式庫與搜尋引擎相混淆。

Lucene是一個全文檢索引擎的架構。那什麼是全文搜尋引擎?

全文搜尋引擎是名副其實的搜尋引擎,國外具代表性的有Google、Fast/AllTheWeb、AltaVista、Inktomi、Teoma、WiseNut等,國內著名的有百度(Baidu)。它們都是通過從網際網路上提取的各個網站的資訊(以網頁文字為主)而建立的資料庫中,檢索與使用者查詢條件匹配的相關記錄,然後按一定的排列順序將結果返回給使用者,因此他們是真正的搜尋引擎。

從搜尋結果來源的角度,全文搜尋引擎又可細分為兩種,一種是擁有自己的檢索程式(Indexer),俗稱“蜘蛛”(Spider)程式或“機器人”(Robot)程式,並自建網頁資料庫,搜尋結果直接從自身的資料庫中呼叫,如上面提到的7家引擎;另一種則是租用其他引擎的資料庫,並按自定的格式排列搜尋結果,如Lycos引擎。

1.3.4 Elasticsearch和Solr比較

  • es基本是開箱即用‘解壓就能用’,非常簡單。Solr安裝略微複雜一丟丟
  • Solr 利用 Zookeeper 進行分散式管理,而 Elasticsearch 自身帶有分散式協調管理功能。
  • Solr 支援更多格式的資料,比如JSON、XML、CSV,而 Elasticsearch 僅支援json檔案格式。
  • Solr 官方提供的功能更多,而 Elasticsearch 本身更注重於核心功能,高階功能多有第三方外掛提供,例如圖形化介面需要kibana友好支撐
  • Solr 查詢快,但更新索引時慢(即插入刪除慢),用於電商等查詢多的應用;ES建立索引快(即查詢慢),即實時性查詢快,用於facebook新浪等搜尋。
  • Solr 是傳統搜尋應用的有力解決方案,但 Elasticsearch 更適用於新興的實時搜尋應用
  • Solr比較成熟,有一個更大,更成熟的使用者、開發和貢獻者社群,而 Elasticsearch相對開發維護者較少,更新太快,學習使用成本較高。

2. ElasticSearch安裝

2.1 下載

官網:https://www.elastic.co/cn/

下載地址: https://www.elastic.co/cn/downloads/elasticsearch

目錄解析:

  • bin:核心檔案,啟動指令碼都在裡邊

  • config: ElasticSearch的一些配置檔案

    • Log4j2 日誌配置檔案
    • jvm.options java虛擬機器相關的配置檔案
    • Elasticsearch.yml Elasticsearch的配置檔案 埠配置等 修改跨域相關
  • jdk:執行環境

  • lib :所需依賴

  • logs:日誌檔案存放地

  • plugins :外掛 ik分詞器等

  • modules:功能模組

2.2 啟動

雙擊 /bin/elasticsearch.bat

測試訪問 http://localhost:9200/

訪問結果

說明成功了

2.3 安裝head外掛

2.3.1 環境前提

node.js環境必須要有,沒有的要先安裝這個環境

2.3.2 下載

https://github.com/mobz/elasticsearch-head/

2.3.3 初始化、啟動

命令:

初始化:npm install 或者 cnpm install

執行:npm run start

2.3.4 測試訪問

http://localhost:9100

但是會發現出現了跨域問題

2.3.5 解決跨域問題

修改ElasticSearch.yml

# 開啟跨域
http.cors.enabled: true
# 配置跨域連線屬性
http.cors.allow-origin: "*"

再次啟動

訪問測試http://localhost:9100

這時候發現有了

head一般用來當做資料展示介面

2.4 安裝kibana

2.4.1 kibana概述

Kibana是一個針對Elasticsearch的開源分析及視覺化平臺 ,用來搜尋、檢視互動儲存在Elasticsearch索引中的資料。使用Kibana ,可以通過各種圖表進行高階資料分析及展示。Kibana讓海量資料更容易理解。它操作簡單,基於瀏覽器的使用者介面可以快速建立儀表板( dashboard )實時顯示Elasticsearch查詢動態。設定Kibana非常簡單。無需編碼或者額外的基礎架構,幾分鐘內就可以完成Kibana安裝並啟動Elasticsearch索索引監測。

2.5.2 安裝前提

node.js 必須,版本和EasticSearch 相同

2.5.3 下載

官網:https://www.elastic.co/cn/downloads/kibana

下載後解壓,解壓這個特別慢,耐心等待

解壓後的目錄

2.5.4 啟動

2.5.5 測試訪問

http://localhost:5601/

發現是英文的

2.5.6漢化

因為kibana是自帶國際化檔案的所以只需要配置一下就好

/config /kibana.yml

i18n.locale: "zh-CN"

修改完之後重啟

再次訪問測試 http://localhost:5601/

成功漢化(^-^)V

3. ES核心概念

1.索引

2.欄位型別(mapping)

3.文件(documents)

叢集,節點,索引,型別,文件,分片,對映是什麼?

3.1 資料庫和ES對比

elasticsearch(叢集)中可以包含多個索引(資料庫),每個索引中可以包含多個型別(表),每個型別下又包 含多 個文件(行),每個文件中又包含多個欄位(列)。

Mysql Elasticsearch
資料庫(database) 索引(indices)
表(table) Types(慢慢會被啟用)
行(row) Documents
欄位(columns) Fields

物理設計:

elasticsearch 在後臺把每個索引劃分成多個分片,每分分片可以在叢集中的不同伺服器間遷移 一個人就是一個叢集!預設的叢集名稱就是 elaticsearh

邏輯設計:

文件

之前說elasticsearch是面向文件的,那麼就意味著索引和搜尋資料的最小單位是文件,elasticsearch 中,文件有幾個 重要屬性 :

  • 自我包含,一篇文件同時包含欄位和對應的值,也就是同時包含 key:value!
  • 可以是層次型的,一個文件中包含自文件,複雜的邏輯實體就是這麼來的! {就是一個json物件! fastjson進行自動轉換!}
  • 靈活的結構,文件不依賴預先定義的模式,我們知道關係型資料庫中,要提前定義欄位才能使用, 在elasticsearch中,對於欄位是非常靈活的,有時候,我們可以忽略該欄位,或者動態的新增一個 新的欄位。

儘管我們可以隨意的新增或者忽略某個欄位,但是,每個欄位的型別非常重要,比如一個年齡欄位類 型,可以是字元 串也可以是整形。因為elasticsearch會儲存欄位和型別之間的對映及其他的設定。這種 對映具體到每個對映的每種型別,這也是為什麼在elasticsearch中,型別有時候也稱為對映型別。

型別

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

索引

類似於mysql中的資料庫

索引是對映型別的容器,elasticsearch中的索引是一個非常大的文件集合。索引儲存了對映型別的欄位 和其他設定。 然後它們被儲存到了各個分片上了。 我們來研究下分片是如何工作的。

物理設計 :節點和分片 如何工作

一個叢集至少有一個節點,而一個節點就是一個elasricsearch程序,節點可以有多個索引預設的,如果 你建立索引,那麼索引將會有個5個分片 ( primary shard ,又稱主分片 ) 構成的,每一個主分片會有一個 副本 ( replica shard ,又稱複製分片 )

上圖是一個有3個節點的叢集,可以看到主分片和對應的複製分片都不會在同一個節點內,這樣有利於某 個節點掛掉 了,資料也不至於丟失。 實際上,一個分片是一個Lucene索引,一個包含倒排索引的檔案 目錄,倒排索引的結構使 得elasticsearch在不掃描全部文件的情況下,就能告訴你哪些文件包含特定的 關鍵字。 不過,等等,倒排索引是什 麼鬼?

倒排索引

elasticsearch使用的是一種稱為倒排索引的結構,採用Lucene倒排索作為底層。這種結構適用於快速的 全文搜尋, 一個索引由文件中所有不重複的列表構成,對於每一個詞,都有一個包含它的文件列表。 例 如,現在有兩個文件, 每個文件包含如下內容:

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

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

現在,我們試圖搜尋 to forever,只需要檢視包含每個詞條的文件 score

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

再來看一個示例,比如我們通過部落格標籤來搜尋部落格文章。那麼倒排索引列表就是這樣的一個結構 :

如果要搜尋含有 python 標籤的文章,那相對於查詢所有原始資料而言,查詢倒排索引後的資料將會快 的多。只需要 檢視標籤這一欄,然後獲取相關的文章ID即可。完全過濾掉無關的所有資料,提高效率!

elasticsearch的索引和Lucene的索引對比

在elasticsearch中, 索引 (庫)這個詞被頻繁使用,這就是術語的使用。 在elasticsearch中,索引被 分為多個分片,每份 分片是一個Lucene的索引。所以一個elasticsearch索引是由多個Lucene索引組成 的。別問為什麼,誰讓elasticsearch使用Lucene作為底層呢! 如無特指,說起索引都是指elasticsearch 的索引。

接下來的一切操作都在kibana中Dev Tools下的Console裡完成。基礎操作!

4. IK分詞器

4.1 什麼是ik分詞器

分詞:即把一段中文或者別的劃分成一個個的關鍵字,我們在搜尋時候會把自己的資訊進行分詞,會把 資料庫中或者索引庫中的資料進行分詞,然後進行一個匹配操作,預設的中文分詞是將每個字看成一個 詞,比如 “我愛狂神” 會被分為"我","愛","狂","神",這顯然是不符合要求的,所以我們需要安裝中文分詞 器ik來解決這個問題。

如果要使用中文,建議使用ik分詞器!

IK提供了兩個分詞演算法:ik_smart 和 ik_max_word,其中 ik_smart 為最少切分,ik_max_word為最細 粒度劃分!一會我們測試!

4.2 下載、安裝

GitHub地址:https://github.com/medcl/elasticsearch-analysis-ik/releases

在plugins 中 建立資料夾 ik 吧檔案解壓這裡面(切記 目錄什麼的不要用中文)

這樣就新增外掛完成了

之後重啟ElasticSearch

日誌中可以看到ik分詞器被載入了

還可以通過

elasticsearch-plugin list

來檢視外掛列表

4.3 kibana使用ik分詞器

ik_smart 和 ik_max_word 接下來這測試這兩種模式

4.3.1 ik_smart最少切分

GET _analyze
{
  "analyzer": "ik_smart",
  "text": "中國萬歲"
}
{
  "tokens" : [
    {
      "token" : "中國",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "萬歲",
      "start_offset" : 5,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 1
    }
  ]
}

4.3.2 ik_max_word 最細 粒度劃分

GET _analyze
{
  "analyzer": "ik_max_word",
  "text": "中國萬歲"
}
{
  "tokens" : [
    {
      "token" : "中國",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "中國",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "國共",
      "start_offset" : 1,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "共產",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "黨",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "CN_CHAR",
      "position" : 5
    },
    {
      "token" : "萬歲",
      "start_offset" : 5,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 6
    },
    {
      "token" : "萬",
      "start_offset" : 5,
      "end_offset" : 6,
      "type" : "TYPE_CNUM",
      "position" : 7
    },
    {
      "token" : "歲",
      "start_offset" : 6,
      "end_offset" : 7,
      "type" : "COUNT",
      "position" : 8
    }
  ]
}

4.3.3 新增自己的詞典

有時候,想要得到自己的詞,結果被拆分了,那怎麼辦呢? 可以通過新增自己的詞典來解決

例如:我們 需要獲得 '學習es'

GET _analyze
{
  "analyzer": "ik_max_word",
  "text": "學習es'"
}
{
  "tokens" : [
    {
      "token" : "學習",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "es",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "ENGLISH",
      "position" : 1
    }
  ]
}

發現學習es被拆開了

下面通過配置解決

1.進入\es\elasticsearch\plugins\ik\config

建立一個 *.dic 這個名字可以是任何

內容:

學習es

儲存後開啟 IKAnalyzer.cfg.xml檔案新增自己的詞典

<entry key="ext_dict">test.dic</entry>

重啟,es、kibana 再次測試

GET _analyze
{
  "analyzer": "ik_max_word",
  "text": "學習es'"
}
{
  "tokens" : [
    {
      "token" : "學習es",
      "start_offset" : 0,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "學習",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "es",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "ENGLISH",
      "position" : 2
    }
  ]
}

5. restful 操作

一種軟體架構風格,而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端和伺服器交 互類的軟體。基於這個風格設計的軟體可以更簡潔,更有層次,更易於實現快取等機制。

基本Rest命令說明:

doc名稱不寫預設是 _doc

method url地址 描述
PUT Host:port/索引名稱/doc名稱/文件id 建立文件(指定文件id)
POST Host:port/索引名稱/doc名稱 建立文件(隨機文件id)
POST Host:port/索引名稱/doc名稱/文件id/_update 修改文件
DELETE Host:port/索引名稱/doc名稱/文件id 刪除文件
GET Host:port/索引名稱/doc名稱/文件id 查詢文件通過文件id
POST Host:port/索引名稱/doc名稱/_search 查詢所有資料

基礎操作

5.1 建立索引

5.1.1 建立一個索引

PUT /索引名/~型別名~/文件id
{
	請求體
}
PUT /indexname/typename/1
{
  "key":"value",
  "key2":"value2"
}
#! Deprecation: [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}).
{
  "_index" : "indexname",
  "_type" : "typename",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

5.1.2 欄位型別

ES常用的資料型別可分為3大類
  • 核⼼資料型別
  • 複雜資料型別
  • 專⽤資料型別
核心資料型別
(1)字串
  • text ⽤於全⽂索引,搜尋時會自動使用分詞器進⾏分詞再匹配
  • keyword 不分詞,搜尋時需要匹配完整的值
(2)數值型
  • 整型: byte,short,integer,long
  • 浮點型: float, half_float, scaled_float,double
(3)日期型別
  • date

json沒有date型別,插入|更新文件|欄位時怎麼表示date型別?

// mapping,將欄位型別設定為date
"type" : "date" 

// 插入|更新此欄位的值時,有3種表示方式

// 使用固定格式的字串
"2020-04-18"、"2020/04/18 09:00:00"   
// 值使用長整型的時間戳,1970-01-01 00:00:00
1610350870    
// 值使用長整型的時間戳,ms
1641886870000
(4)範圍型

integer_range, long_range, float_range,double_range,date_range

比如招聘要求年齡在[20, 40]上,mapping:

age_limit :{
 "type" : "integer_range"
}

插入|更新文件|欄位時,值寫成json物件的形式:

gt是大於,lt是小於,e是equals等於。

"age_limit" : {
 "gte" : 20,
 "lte" : 40
}

按此欄位搜尋時,值寫常量:

age_limit的區間包含了此值的文件都算是匹配。

"term" : {
 "age_limit" : 30
}
(5)布林
  • boolean #true、false
(6)⼆進位制
  • binary 會把值當做經過 base64 編碼的字串,預設不儲存,且不可搜尋
複雜資料型別
(1)物件
  • object

一個物件中可以巢狀物件。

// 定義mapping
"user" : {
    "type":"object"
}

// 插入|更新欄位的值,值寫成json物件的形式
"user" : {
    "name":"chy",
    "age":12
}

// 搜尋時,欄位名使用點號連線
"match":{
     "user.name":"chy"
 }

(2)陣列
// ES沒有專門的陣列型別,定義mapping,寫成元素的型別
"arr" : {
    "type":"integer"
}

// 插入|更新欄位的值。元素可以是各種型別,但元素的型別要相同
"arr" : [1,3,4]
專用資料型別
  • ip
// 定義mapping
"ip_address" : {
    "type":"ip"
}

// 插入|更新欄位的值,值寫成字串形式
"ip" : "192.168.1.1"

// 搜尋
"match":{
     "ip_address":"192.168.1.1"
 }

// ip在192.168.0.0 ~ 192.168.255.255上的文件都匹配
"match":{
     "ip_address":"192.168.0.0/16"
 }
自定義資料型別

如果自己的文件沒有指定,那麼ES就會給我們預設配置欄位型別!

PUT /text1 // 建立索引規則
{
  "mappings": {
    // 屬性
    "properties": {
      // 欄位
      "field":{  
        "type": "text"
      },
      "fiele2":{
        "type": "long"
      }
    }
  }
}
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "text1"
}

5.1.3 獲取屬性資訊

// 獲取索引資訊
GET 索引名
// 獲取文件資訊
GET 索引名/型別/文件ID
// 通過 _cat/可以獲得更多資訊
GET _cat/...
GET _cat/health // 獲取健康資訊
GET _cat/indices?v // 檢視預設的配置

5.1.4 修改屬性值

修改 提交還是使用PUT方法即可 覆蓋原來資料進行修改操作(version會增加,result:"update")

使用POST更新 (更改請求方式在GET基礎上後面加上 /_update

5.1.5 刪除索引

使用DELETE請求更換GET請求(不需要帶請求體) 完成刪除操作

5.2 文件操作

5.2.1 文件插入

與索引插入一致

PUT /indexname/typename/1
{
  "key":"value",
  "key2":"value2"
}
PUT /indexname/typename/2
{
  "key":"value",
  "key2":"value2"
}
PUT /indexname/typename/3
{
  "key":"value",
  "key2":"value2"
}

5.2.2 文件查詢

// 簡單查詢
// /_search?q 代表query 後面跟條件(key=value)多個用&&連線 根據預設的對映規則查詢
GET /indexname/typename/_search?q=key:value
// 複雜查詢
GET /indexname/typename/_search
{
  // 查詢
  "query":{
    // 查詢條件 
    // match 匹配 會使用分詞器解析
  	// term 精準查詢 直接是通過倒排索引指定的詞條進行精確的查詢  
    "match":{  
      // 查詢欄位:查詢值
      "FIELD":"VALUE"
       // 查詢欄位:查詢值
       // 多個條件使用空格隔開
      "FIELD2":"VALUE2 VALUE3"
    }
    
    
    // 布林查詢
    "bool":{
      // must 代表 and
      "must":{
        // 查詢條件
        "match":{
          // 查詢欄位:查詢值
          "FIELD":"VALUE"
        }
      }

      // should 代表 or
      "should":{
      	// 查詢條件
        "match":{
          // 查詢欄位:查詢值
          "FIELD":"VALUE"
        }
    	}
			
			// must_not 代表 not
			"must_not":{
        // 查詢條件
        "match":{
          // 查詢欄位:查詢值
          "FIELD":"VALUE"
        }
      }
			
			// filter 自定義過濾器(條件過濾)
			"filter":{
        // range 範圍
        "range":{
          // 欄位:{條件:值}
          "FIELD":{
            // FIELD 大於 10
            "gt": 10,
            // FIELD 大於等於 10
            "gte": 10,
            // FIELD 小於 10
            "lt":10,
            // FIELD 小於等於 10
            "lte":10,
          }
        }
      }
			

    }
  }


  // 結果過濾,如果不寫預設查詢所有欄位
  "_source":["key1","key2"]


	// 排序
	// 會使命中權重 `_score=null`
	"sort":[
    // 根據那個欄位排序
    // desc 降序 asc 升序
    "FIELD":"desc"
  ]


	// 分頁 
	// from 和 size 同時出現
	// from 從第幾條開始 size 返回多少條資料
	"from":0
	"size":1

	// 高亮
	"highlight":{
    // 高亮欄位
    "fields":{
      // 欄位名稱:{} 符合的結果會自動帶上一個html標籤
      // 預設是<em></em>標籤
      "key":{}
    }
    // 設定自定義標籤字首
    "pre_tags":"<自定義 class=xxx ...>"
    // 設定自定義字尾
    "post_tags":"</自定義>"
  }
}

補充:

  • 關於match 與 term的區別
    • match(先分析文件,然後在通過分詞器進行解析) 速度沒有term快
    • term是精準查詢 速度快
  • query:根據引數查詢
  • _source:過濾需要返回的欄位
  • sort:排序
  • form、size 設定分頁
  • bool查詢
    • must 代表 and
    • should 代表 or
    • must_not 代表 not
  • filter條件過濾
    • gt 大於
    • gte 大於等於
    • lt 小於
    • lte 小於等於
  • 一個欄位多個條件使用空格隔開即可
  • text 和 keyword 型別
    • text型別可以被分詞器解析
    • keyword不能被分詞器解析,也就是說只能做精準查詢
  • highlight 高亮設定