elasticsearch倒排索引原理與中文分詞器

1. 索引的方式:

1.1 正向索引
正排表是以文檔的ID爲關鍵字,表中記錄文檔中每個字的位置信息,查找時掃描表中每個文檔中字的信息直到找出所有包含查詢關鍵字的文檔。
這種組織方法在建立索引的時候結構比較簡單,建立比較方便且易於維護;因爲索引是基於文檔建立的,若是有新的文檔加入,直接爲該文檔建立一個新的索引塊,掛接在原來索引文件的後面。若是有文檔刪除,則直接找到該文檔號文檔對應的索引信息,將其直接刪除。但是在查詢的時候需對所有的文檔進行掃描以確保沒有遺漏,這樣就使得檢索時間大大延長,檢索效率低下。
儘管正排表的工作原理非常的簡單,但是由於其檢索效率太低,除非在特定情況下,否則實用性價值不大。
1.2 倒排索引
倒排表以字或詞爲關鍵字進行索引,表中關鍵字所對應的記錄表項記錄了出現這個字或詞的所有文檔,一個表項就是一個字表段,它記錄該文檔的ID和字符在該文檔中出現的位置情況。
由於每個字或詞對應的文檔數量在動態變化,所以倒排表的建立和維護都較爲複雜,但是在查詢的時候由於可以一次得到查詢關鍵字所對應的所有文檔,所以效率高於正排表。在全文檢索中,檢索的快速響應是一個最爲關鍵的性能,而索引建立由於在後臺進行,儘管效率相對低一些,但不會影響整個搜索引擎的效率。

1.3 總結
正排索引是從文檔到關鍵字的映射(已知文檔求關鍵字),倒排索引是從關鍵字到文檔的映射(已知關鍵字求文檔)。通俗的來說,正向索引可以看作是查找所有文檔,然後再去尋找關鍵字,而倒排索引是通過關鍵字做索引,然後找索引所對應的文檔。
倒排索引在這裏插入圖片描述

2. 高級查詢

根據id進行查詢 
GET /mymayikt/user/12
查詢當前所有類型的文檔 
GET /mymayikt/user/_search

根據多個ID批量查詢 
查詢多個id分別爲12
GET /mymayikt/user/_mget
{
  "ids":["1","2"]
  
}

複雜條件查詢
查詢年齡爲年齡21歲

GET /mymayikt/user/_search?q=age:21

查詢年齡30歲-60歲之間

GET /mymayikt/user/_search?q=age[30 TO 60]
注意:TO 一定要大寫

查詢年齡30歲-60歲之間 並且年齡降序、從0條數據到第1條數據

GET /mymayikt/user/_search?q=age[30 TO 60]&sort=age:desc&from=0&size=1

查詢年齡30歲-60歲之間 並且年齡降序、從0條數據到第1條數據,展示name和age字段

GET /mymayikt/user/_search?q=age[30 TO 60]&sort=age:desc&from=0&size=1
&_source=name,age

Dsl語言查詢與過濾
什麼是DSL語言
es中的查詢請求有兩種方式,一種是簡易版的查詢,另外一種是使用JSON完整的請求體,叫做結構化查詢(DSL)。
由於DSL查詢更爲直觀也更爲簡易,所以大都使用這種方式。
DSL查詢是POST過去一個json,由於post的請求是json格式的,所以存在很多靈活性,也有很多形式。

根據名稱精確查詢姓名

GET mymayikt/user/_search
{
  "query": {
    "term": {
      "name": "xiaoming"
    }
  }
  
}

##term是代表完全匹配,即不進行分詞器分析,文檔中必須包含整個搜索的詞彙
根據汽車名稱模糊查詢

GET /mymayikt/user/_search
{
  "from": 0,
  "size": 2, 
  "query": {
    "match": {
      
        "car": "奧迪"
      }
  }
}

####match查詢相當於模糊匹配,只包含其中一部分關鍵詞就行

Term與Match區別

Term查詢不會對字段進行分詞查詢,會採用精確匹配。
Match會根據該字段的分詞器,進行分詞查詢。

使用filter過濾年齡

GET /mymayikt/user/_search
{
	"query": {
		"bool": {
			"must": [{
				"match_all": {}
			}],
			"filter": {
				"range": {
					"age": {
						"gt": 21,
						"lte": 51
					}
				}

			}

		}

	},
	"from": 0,
	"size": 10,
	"_source": ["name", "age"]

}

3.分詞器

3.1 什麼是分詞器

因爲Elasticsearch中默認的標準分詞器分詞器對中文分詞不是很友好,會將中文詞語拆分成一個一箇中文的漢子。因此引入中文分詞器-es-ik插件

演示傳統分詞器
http://192.168.223.130:9200/_analyze
{
“analyzer”: “standard”,
“text”: “奧迪a4l”
}
{"analyzer": "standard","text": "奧迪a4l"}

下載地址: https://github.com/medcl/elasticsearch-analysis-ik/releases
注意: es-ik分詞插件版本一定要和es安裝的版本對應
第一步:下載es的IK插件(資料中有)命名改爲ik插件
第二步: 上傳到/usr/local/elasticsearch-6.4.3/plugins
第三步: 重啓elasticsearch即可

http://192.168.223.130:9200/_analyze
{
“analyzer”: “ik_smart”,
“text”: “奧迪”
}

{"analyzer": "ik_smart","text": "奧迪"}

自定義擴展字典

/usr/local/elasticsearch-6.4.3/plugins/ik/config目錄下
mkdir custom
vi custom/new_word.dic
老鐵
王者榮耀
洪荒之力
共有產權房
一帶一路
餘勝軍

vi IKAnalyzer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>IK Analyzer 擴展配置</comment>
    <!--用戶可以在這裏配置自己的擴展字典 -->
    <entry key="ext_dict">custom/new_word.dic</entry>
     <!--用戶可以在這裏配置自己的擴展停止詞字典-->
    <entry key="ext_stopwords"></entry>
    <!--用戶可以在這裏配置遠程擴展字典 -->
    <!-- <entry key="remote_ext_dict">words_location</entry> -->
    <!--用戶可以在這裏配置遠程擴展停止詞字典-->
    <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

文檔映射
已經把ElasticSearch的核心概念和關係數據庫做了一個對比,索引(index)相當於數據庫,類型(type)相當於數據表,映射(Mapping)相當於數據表的表結構。ElasticSearch中的映射(Mapping)用來定義一個文檔,可以定義所包含的字段以及字段的類型、分詞器及屬性等等。
文檔映射就是給文檔中的字段指定字段類型、分詞器。
使用GET /mymayikt/user/_mapping

映射的分類
動態映射

我們知道,在關係數據庫中,需要事先創建數據庫,然後在該數據庫實例下創建數據表,然後才能在該數據表中插入數據。而ElasticSearch中不需要事先定義映射(Mapping),文檔寫入ElasticSearch時,會根據文檔字段自動識別類型,這種機制稱之爲動態映射。
靜態映射
在ElasticSearch中也可以事先定義好映射,包含文檔的各個字段及其類型等,這種方式稱之爲靜態映射。
ES類型支持

基本類型
符串:string,string類型包含 text 和 keyword。

text:該類型被用來索引長文本,在創建索引前會將這些文本進行分詞,轉化爲詞的組合,建立索引;允許es來檢索這些詞,text類型不能用來排序和聚合。
keyword:該類型不需要進行分詞,可以被用來檢索過濾、排序和聚合,keyword類型自讀那隻能用本身來進行檢索(不可用text分詞後的模糊檢索)。
注意: keyword類型不能分詞,Text類型可以分詞查詢
數指型:long、integer、short、byte、double、float
日期型:date
布爾型:boolean
二進制型:binary
數組類型(Array datatype)
複雜類型
地理位置類型(Geo datatypes)
地理座標類型(Geo-point datatype):geo_point 用於經緯度座標
地理形狀類型(Geo-Shape datatype):geo_shape 用於類似於多邊形的複雜形狀

特定類型(Specialised datatypes)
Pv4 類型(IPv4 datatype):ip 用於IPv4 地址
Completion 類型(Completion datatype):completion 提供自動補全建議
Token count 類型(Token count datatype):token_count 用於統計做子標記的字段的index數目,該值會一直增加,不會因爲過濾條件而減少
mapper-murmur3 類型:通過插件,可以通過_murmur3_來計算index的哈希值
附加類型(Attachment datatype):採用mapper-attachments插件,可支持_attachments_索引,例如 Microsoft office 格式,Open Documnet 格式, ePub,HTML

Analyzer 索引分詞器,索引創建的時候使用的分詞器 比如ik_smart
Search_analyzer 搜索字段的值時,指定的分詞器

創建文檔類型並且指定類型

POST /mymayikt/_mapping/user
{
  "user":{
    "properties":{
       "age":{
         "type":"integer"
       },
        "sex":{
         "type":"integer"
       },
       "name":{
         "type":"text",
         "analyzer":"ik_smart",
         "search_analyzer":"ik_smart"
       },
       "car":{
         "type":"keyword"
      
       }
    }
  }
  
}
http://192.168.223.130:9200/_cat/nodes?pretty
請求地址/索引/_settings
http://192.168.223.130:9200/mymayikt/_settings
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章