.Net Core中使用ElasticSearch(一)

一、安裝配置

在官網下載Es,注意版本號,不同大版本號之間差異很大。我安裝的是7.14.0版本

1.1 安裝成服務

  cmd 進入bin目錄下執行

elasticsearch-service.bat install

1.2 安裝插件

  ik分詞器,分詞器的版本和ES版本需要一致

elasticsearch-plugin.bat install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.14.0/elasticsearch-analysis-ik-7.14.0.zip

1.3 配置賬號密碼

修改config目錄下面的elasticsearch.yml文件,在裏面添加如下內容,並重啓。

xpack.security.enabled: true
xpack.license.self_generated.type: basic
xpack.security.transport.ssl.enabled: true

執行:

elasticsearch-setup-passwords interactive

然後配置每個賬戶密碼。

通過賬號密碼鏈接: http://username:[email protected]:9200

二、基礎概念

2.1 文檔元數據

節點

說明

_index

文檔存儲的地方,必須小寫,不能以下劃線開頭,不能包含逗號

_type

文檔代表的對象的類,命名可以是大寫或者小寫,但是不能以下劃線或者句號開頭,不應該包含逗號

_id

文檔的唯一標識

2.2 索引

一個 索引 類似於傳統關係數據庫中的一個 數據庫 ,是一個存儲關係型文檔的地方。事實上,我們的數據被存儲在分片(shards)中,索引只是一個把一個或多個分片分組在一起的邏輯空間。

2.3 文檔

文檔指最頂層結構或根對象序列化的JSON數據(以唯一Id標識並存儲於ES中),相當於關係數據的行。在版本7.0中已經沒有文檔了,統一爲“_doc”。

三、數據的物理存儲

  ES爲什麼能搜索和存儲海量數據呢?是因爲它的水平拓展,它內部分將整個數據進行分片,每個分片存儲部分數據。

 如圖:將整個數據分爲5片,每一片都有一個副本,5個主分片分別存儲在不同節點。每個節點就是一個ElasticSearch實例。

 

3.1 數據是怎麼存儲到分片中的?

  在創建索引時,主分片的數量和其副本的數量已經確定了,當創建文檔時,Es會根據文檔的Id值選擇一個主分片,可能這個主分片,在另一個節點。文檔被髮送到主分片和該主分片所有的副分片中。在新建一個文檔的時候, Elasticsearch 如何知道一個文檔應該存放到哪個分片中呢?首先這肯定不會是隨機的,否則將來要獲取文檔的時候我們就不知道從何處尋找了。實際上,這個過程是根據下面這個公式決定的:

shard = hash(routing) % number_of_primary_shards

routing 是一個可變值,默認是文檔的 _id ,也可以設置成一個自定義的值。這就解釋了爲什麼我們要在創建索引的時候就確定好主分片的數量 並且永遠不會改變這個數量:因爲如果數量變化了,那麼所有之前路由的值都會無效,文檔也再也找不到了。

新建、索引、刪除操作,必須在主分片上完成後才能被複制到相關副分片。

3.2 多個節點查詢的過程

  當其中一個節點接收到搜索請求時,會將請求轉發到其他節點,然後將每個節點的結果聚集返回。在默認情況下,搜索請求通過round-robin輪詢機制選中主分片和副分片。

 

 

3.3 爲什麼ElasticSearch查詢快?

  Es爲了查詢速度,使用的是倒排索引。假如存儲的兩個個文檔中Content字段值爲:

  1:My nickname is Microheart.

  2:Hello Microheart

  爲了創建倒排索引,Es首先將每個文檔的 content 值拆分成單獨的詞(也就是tokens),創建一個包含所有不重複詞條的排序列表,然後列出每個詞條出現在哪個文檔。

my

1

nickname

1

is

1

microheart

1,2

hello

2

 
 如果我們此時查詢 microheart ,2個文檔都會出現。但是文檔2的長度短,搜索詞條佔比大,所以匹配度更高。倒排索引的特點就是不需要直接查詢內容,根據詞匹配,找到匹配文檔的Id。

3.4 相關性

  上面的例子,提到了相關性,相關性主要根據下面三個有關:

  • 檢索詞頻率:檢索詞在該字段出現的頻率,出現頻率越高,相關性也越高。 字段中出現過 5 次要比只出現過 1 次的相關性高。
  • 反向文檔頻率:每個檢索詞在索引中出現的頻率,頻率越高,相關性越低。檢索詞出現在多數文檔中會比出現在少數文檔中的權重更低。
  • 字段長度準則:字段的長度是多少?長度越長,相關性越低。 檢索詞出現在一個短的 title 要比同樣的詞出現在一個長的 content 字段權重更大。

3.5 映射

域映射:域最重要的屬性是type,就是字段類型。對於非string的域,只需要設置type

string域映射有兩個重要的屬性 index和 analyzer

Index:控制怎樣索引字符串

  • analyzed :首先分析字符串,然後索引它。換句話說,以全文索引這個域。
  • not_analyzed:索引這個域,所以它能夠被搜索,但索引的是精確值。不會對它進行分析。
  • no:不索引這個域。這個域不會被搜索到。

analyzer:指定分詞器

  上面的例子中,爲什麼會按照單詞拆詞呢?因爲默認不指定分詞器,就是standard分詞器,它會按照英文單詞拆詞。分詞器有:snowball、standard、keyword、ik_smart、ik_max_word。其中ik_smart和ik_max_word是中文的分詞

 ES 2.x版本中只有string類型,ES 5.x以後,只有text 和 keyword字段。

比如一篇博客,有標題和內容兩個字段,指定爲ik_smart。假如標題爲 “.Net Core中使用ElasticSearch”,就會被拆詞爲 “net”、“core”、 "中"、“使用”、“elasticsearch”。如果用戶搜索“.net core”,應該對用戶的搜索詞也進行拆詞,拆分爲 “net”、“core”,那麼標題就會命中。

        /// <summary>
        /// 標題
        /// </summary>
        [Text(Analyzer = "ik_smart")]
        public string Title { get; set; }

        /// <summary>
        /// 內容
        /// </summary>
        [Text(Analyzer = "ik_smart")]
        public string Content { get; set; }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章