Elasticsearch基本知識

ES是一個基于Apache的開源索引庫Lucene而構建的 開源、分布式、具有RESTful接口的全文搜索引擎, 還是一個分布式文檔數據庫.


一、基本概念

1.index:

索引是具有相似結構的文檔的集合, 比如可以有一個商品分類索引, 訂單索引.

每個索引都要有唯一的名稱, 名稱要小寫, 通過索引名稱來執行索引、搜索、更新和刪除等操作.

一個集群中可以有任意多個索引, 只要保證名稱不同即可

2.document

文檔是存儲在ES中的一個個JSON格式的字符串, 是ES索引中的最小數據單元, 由field(字段)構成.

ES是一個非結構化的數據庫,每個文檔可以有不同的字段,并且有一個唯一標識.

3.field

字段可以是一個簡單的值(如字符串、數字、日期), 也可以是一個數組, 還可以嵌套一個對象或多個對象.

字段類似于關系數據庫中表數據的列, 每個字段都對應一個類型.

可以指定如何分析某一字段的值, 即對field指定分詞器

4.type

一個索引中,可以定義一個或者多個類型(7.x版本中被廢棄,8.x版本中已移除)

5.text

文本是field類型的一種, 通常會被分析成多個Term, 存儲在ES的索引庫中.

6.mapping

類似于關系數據庫中的Table結構, 每個index都有一個映射: 定義索引中每個字段的類型.

所有文檔在寫進索引之前都會先進行分析, 如何對文本進行分詞、哪些詞條又會被過濾, 這類行為叫做映射(mapping).

映射可以提前定義, 也可以在第一次存儲文檔時自動識別.

7.analysis

將文本轉換為索引詞的過程, 分析的結果依賴于分詞器

240015.jpg

二、基本原理
正排索引:通過記錄id查詢內容記錄;

倒排索引:通過內容關鍵詞獲取記錄id。ES寫入數據時,會把數據進行分詞,把每一個分詞的結果與文檔進行關聯,再把相同的詞所關聯的文檔進行合并,建立倒排索引。

三、ES的字段
es的字段都有一個字段類型,不同的類型都各有所長,比如keyword類型的字段適合做聚合和排序,而text的類型可以用來全文搜索。下面按大類介紹下es常用的數據類型,es的數據字段的類型定義和搜索的方式緊密相關,

例如 keyword類型,Number類型在搜索時,只適合精準匹配,范圍搜索之類的,不能用于全文搜索。而text類型適合全文搜索。



1.Common types

1.1 binary

二進制類型 ,值以base64字符串的形式存貯,_source默認不會存貯該類型的值,如果需要實際的存貯,請設置 store屬性為true默認是false

type:binary

PUT my-index-000003
{
  "mappings": {
    "properties": {

      "blob": {
        "type": "binary",
        "store": true
      }
    }
  }
}

PUT my-index-000003/_doc/2
{
  "blob": "U29tZSBiaW5hcnkgYmxvYg=="
}


1.1 boolean

布爾類型

type:boolean

true :true,“true"都可以表示 true

false: false,“false”,”" 都可以表示 false



PUT my-index-000003
{
  "mappings": {
    "properties": {

      "boolean_field": {
        "type": "boolean"
      }
    }
  }
}


PUT my-index-000003/_doc/2
{
  "boolean_field": "false"
}


1.2 Keywords

keywords大家庭包括 keyword,constant_keyword,widecard



keyword:類型的字段適合聚合(aggragate)和排序(sort)操作,term和term_level查詢比較快,如果字段的值都是數字,但term查詢比較多,可以考慮定義keyword類型,而不是interger或者其他數字類型,



constant_keyword:所有文檔的該字段的值都是一樣的,可以定義該類型



widecard:適合通配符搜索日志等場景 ,text類型不支持通配符搜索,但widecard 在聚合和排序的性能會低于其他keyword類型,而且如果前導詞是通配符,搜索效率相對會比較慢。



PUT my-index-000003/_mapping
{

    "properties": {
      "my_keyword":{
        "type": "keyword"
      },
      "my_constant_keyword":{
        "type": "constant_keyword",
        "value":"constant"
      },
      "my_wildcard": {
        "type": "wildcard"
      }
    }

}


PUT my-index-000003/_doc/1
{
  "my_keyword":"keyword",
  "my_wildcard" : "This string can be quite lengthy"
}


GET my-index-000003/_search
{
  "query": {
    "wildcard": {
      "my_wildcard": {
        "value": "*quite*"
      }
    }
  }
}


1.3 Numbers

數字類型:包括整數和浮點數類型,有 short,interger,long unsigned_long,

float,double,half_float,scaled_float(底層是以long類型存貯的,需要配置scaled_factor ,浮點數*scaled_factor,比如價格一般是2位小數 ,如果scaled_factor配置為100 ,某個文檔的該類型字段的值為 98.99,那么底層存貯 9899,相對于直接存double,節約了存貯空間),不是該字段存的是數字類型就一定要定義數字類型,數字類型在range查詢,和一些數值計算查詢相對會快,但是如果是term查詢不如keyword類型。



PUT /my-index-000003/_mapping
{

    "properties": {
      "number_of_bytes": {
        "type": "integer"
      },
      "time_in_seconds": {
        "type": "float"
      },
      "price": {
        "type": "scaled_float",
        "scaling_factor": 100
      }
    }

}


1.4 Dates

日期類型包括 date和date_nanos.類型,

date類型可以通過format屬性指定字段值的日期格式, || 連接多種格式

如果沒有顯示的指定format的屬性值,默認為"strict_date_optional_time||epoch_millis"

"strict_date_optional_time"為常規的iso日期時間轉換器,格式“yyyy-MM-dd ‘T’ HH:mm:ss.SSSZ” or “yyyy-MM-dd”,es默認內置了很多日期格式,大家可以翻閱文檔查看



PUT my-index-000003/_mapping
{

    "properties": {
      "create_time":{
        "type": "date",
        "format":"yyyy-MM-dd HH:mm:ss"
      }
    }

}


POST my-index-000003/_doc
{
  "create_time":"2021-05-15 23:14:55"

}








1.5 alias

為已存在的字段定義別名,別名可用于卻大多數搜索api和field capabilities 。目前不是和寫入api,比如添加或者更新等操作。



type : “alias”, path為當前目標字段的路徑,如果該字段是有父類對象,

則path為 parentObject1.parentObject2.target_field



例如:



PUT /my-index-000003

{

  "mappings": {

    "properties": {

      "user_name":{

        "type": "text"

      },

      "name":{

        "type": "alias",

        "path" :"user_name"

      },

      "friends":{

        "type": "nested",

        "properties": {

          "friends_name":{

            "type":"text"

          },

          "f_name":{

            "type": "alias",

            "path":"friends.friends_name"

          }

        }



      }



    }

  }

}





POST /my-index-000003/_doc/1

{

  "user_name":"ly",

  "frends":{

    "friends_name":"luck"

  }

}



GET /my-index-000003/_search?pretty

{

  "query": {

    "match": {

      "name": "ly"

    }

  }

}


2.Objects and relational types(對象關系類型)
2.1 object

對象類型:字段值是一個json對象

POST customer/_doc/3
{
  "name":"孫七",
  "state":1,
  "create_time":"2021-03-14 18:00:00",
  "other":{
    "age":27,
    "address":"beijin",
    "phone":"10010"
  }
}


不顯示指定字段類型,直接往里添加文檔也是可以的,es默認會幫我們創建合適的類型,其他對象類型還有flattened,nested,join在object的基礎上,提供了自己的一些特性,彌補了object的不足



3.Text search types(文本搜索類型)

text是全文搜索類型,在建立索引和搜索時,輸入的文本會經過分析器處理(Analyzed),分析器會對其進行過濾,分詞,轉換等操作。es內置了多種分析器,而且我們可以定義分析器。

只有text類型才能用于match,match_phrase等搜索語句,

PUT /my-index-000003
{
  "mappings": {
    "properties": {
      "user_name":{
        "type": "text"
      }

    }
  }
}


POST /my-index-000003/_doc
{
  "user_name":"jack liu"
}


GET /my-index-000003/_search
{
  "query": {
    "match": {
      "user_name": "jack"
    }
  }
}
4. Arrays 數組類型

es沒有專門的數組類型,所有類型字段都可以一個或者多個值,只是多個值得類型必須相同。



PUT my-index-000001/_doc/1

{

  "message": "some arrays in this document...",

  "tags":  [ "elasticsearch", "wow" ],

  "lists": [

    {

      "name": "prog_list",

      "description": "programming list"

    },

    {

      "name": "cool_list",

      "description": "cool stuff list"

    }

  ]

}




作者:碼農編程進階筆記


歡迎關注微信公眾號 :碼農編程進階筆記