日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

Elasticsearch數據源

本文介紹云數據庫 SelectDB 版與Elasticsearch(簡稱ES)數據源進行對接使用的流程,幫助您對Elasticsearch數據源進行聯邦分析。

概述

Elasticsearch Catalog除了支持自動映射ES元數據外,也可以結合SelectDB的分布式查詢規劃能力和ES的全文檢索能力,提供更完善的OLAP分析場景解決方案。可以體現在:

  • ES中多Index分布式Join查詢。

  • SelectDB和ES中的表聯合查詢,實現更復雜的全文檢索過濾。

當前SelectDB支持Elasticsearch 5.x及以上版本。

創建Catalog

CREATE CATALOG test_es PROPERTIES (
    "type"="es",
    "hosts"="http://127.0.0.1:9200",
    "user"="test_user",
    "password"="test_passwd",
    "nodes_discovery"="false"
);

因為Elasticsearch沒有庫(Database)的概念,所以連接ES后,會自動生成一個唯一的庫:default_db,并且在通過SWITCH命令切換到ES Catalog后,會自動切換到default_db庫,無需再執行USE default_db命令。

參數說明:

參數

是否必選

默認值

說明

hosts

ES地址,可以是一個或多個,也可以是ES的負載均衡地址。

user

ES的賬號。

password

對應賬號的密碼。

doc_value_scan

true

是否開啟通過ES或Lucene列式存儲獲取查詢字段的值。

keyword_sniff

true

是否對ES中字符串分詞類型text.fields進行探測,通過keyword進行查詢。設置為false會按照分詞后的內容匹配。

nodes_discovery

true

是否開啟ES節點發現,默認為true。

說明

阿里云ES服務采用負載均衡服務作為ES請求入口,無法直接訪問集群節點,這里需設置為false。

ssl

false

ES是否開啟HTTPS訪問模式,目前在fe/be實現方式為信任所有。

mapping_es_id

false

是否映射ES索引中的_id字段。

like_push_down

true

是否將like轉化為wildchard下推到ES,會增加ES的CPU消耗。

include_hidden_index

false

是否包含隱藏的索引,默認為false。

說明
  • 認證方式目前僅支持HTTP Basic認證,并且需要確保該賬號具有訪問/_cluster/state/_nodes/http等路徑和讀取index的權限;若集群未開啟安全認證,則不需要設置賬號和密碼。

  • 當ES 5.x和 6.x中一個index中存在多個type時,SelectDB默認讀取第一個。

查詢用法

在SelectDB中建立ES Catalog后,除了無法使用SelectDB中的數據模型(ROLLUP、預聚合、物化視圖等)外,與在SelectDB查詢普通表并無區別。

基本查詢

SELECT * FROM es_table WHERE k1 > 1000 AND k3 ='term' OR k4 LIKE 'fu*z_';

擴展的esquery

通過esquery(field, QueryDSL)函數,可以將一些無法用SQL表述的Query如match_phrasegeoshape等下推給ES進行過濾處理。esquery的第一個列名參數用于關聯index,第二個參數是ES的基本Query DSL的JSON表述,使用花括號{}將參數包含在其中。JSON的root key有且只能有一個,如match_phrasegeo_shapebool等。示例如下:

match_phrase查詢:

SELECT * FROM es_table WHERE esquery(k4, '{ "match_phrase": { "k4": "selectdb on es" } }');

geo_shape查詢:

SELECT * FROM es_table WHERE esquery(k4, '{ "geo_shape": { "location": { "shape": { "type": "envelope", "coordinates": [ [ 13, 53 ], [ 14, 52 ] ] }, "relation": "within" } } }');

bool查詢:

SELECT * FROM es_table WHERE esquery(k4, ' { "bool": { "must": [ { "terms": { "k1": [ 11, 12 ] } }, { "terms": { "k2": [ 100 ] } } ] } }');

列類型映射

ES Type

SelectDB Type

備注

null

null

boolean

boolean

byte

tinyint

short

smallint

integer

int

long

bigint

unsigned_long

largeint

float

float

half_float

float

double

double

scaled_float

double

date

date

僅支持default/yyyy-MM-dd HH:mm:ss/yyyy-MM-dd/epoch_millis格式。

keyword

string

text

string

ip

string

nested

string

object

string

other

unsupported

Array類型

Elasticsearch沒有明確的數組類型,但是它的某個字段可以含有0個或多個值。 為了表示一個字段是數組類型,可以在索引映射的_meta部分添加特定的selectdb結構注釋。對于Elasticsearch 6.x及之前版本,請參考_meta

舉例說明,假設有一個索引doc包含以下的數據結構:

{
  "array_int_field": [1, 2, 3, 4],
  "array_string_field": ["selectdb", "is", "the", "best"],
  "id_field": "id-xxx-xxx",
  "timestamp_field": "2022-11-12T12:08:56Z",
  "array_object_field": [
    {
      "name": "xxx",
      "age": 18
    }
  ]
}

該結構的數組字段,可通過如下命令將字段屬性定義添加到目標索引映射的_meta.selectdb屬性來定義。

# ES 7.x and above
curl -X PUT "localhost:9200/doc/_mapping?pretty" -H 'Content-Type:application/json' -d '
{
    "_meta": {
        "selectdb":{
            "array_fields":[
                "array_int_field",
                "array_string_field",
                "array_object_field"
            ]
        }
    }
}'

# ES 6.x and before
curl -X PUT "localhost:9200/doc/_mapping?pretty" -H 'Content-Type: application/json' -d '
{
    "_doc": {
        "_meta": {
            "selectdb":{
                "array_fields":[
                    "array_int_field",
                    "array_string_field",
                    "array_object_field"
                ]
            }
    }
    }
}

array_fields:用來表示是數組類型的字段。

最佳實踐

過濾條件下推

ES Catalog支持過濾條件的下推,即將過濾條件下推給ES,僅返回真正滿足條件的數據,顯著地提高查詢性能,降低SelectDB和Elasticsearch的CPU、內存及IO使用量。

下面的操作符(Operators)會被優化成如下ES Query:

SQL syntax

ES 5.x+ syntax

=

term query

in

terms query

> , < , >= , ?

range query

and

bool.filter

or

bool.should

not

bool.must_not

not in

bool.must_not + terms query

is_not_null

exists query

is_null

bool.must_not + exists query

esquery

ES原生JSON形式的QueryDSL

啟用列式掃描優化查詢速度

通過設置"enable_docvalue_scan" = "true",可以啟用列式掃描,以優化查詢速度。

開啟后,SelectDB在通過ES查詢數據的過程中,會遵循以下兩個原則:

  • 盡力而為:自動探測待查詢的字段是否開啟列式存儲(doc_value: true),如果待查詢字段全部已開啟列式存儲,SelectDB會從列式存儲中獲取所有字段的值。

  • 自動降級:如果待查詢的字段中有一個字段沒有列存,所有字段都會從行存(_source)中解析獲取。

默認情況下,SelectDB On ES會從行存(_source)中獲取所需的所有列,_source的存儲采用的行式+JSON的形式存儲,在批量讀取性能上要劣于列式存儲,尤其是在只需要查詢少數列的情況下尤為明顯。在只查詢少數列的情況下,docvalue的性能大約是_source性能的十幾倍。

重要
  • text類型的字段在ES中沒有列式存儲,因此如果要獲取的字段值有text類型字段,SelectDB會自動降級為從_source中獲取。

  • 當獲取的字段數量過多(大于等于25)時,從docvalue中獲取字段值的性能與從_source中獲取字段值基本一樣。

探測keyword類型字段

通過設置"enable_keyword_sniff" = "true",可以啟用keyword類型字段探測。

在ES中可以不創建index直接進行數據導入,此時ES會自動創建一個新的索引。針對字符串類型的字段,ES會創建一個既有text類型的字段,又有keyword類型的字段,這是ES的multi fields特性。

例如如下的mapping:

"k4": {
   "type": "text",
   "fields": {
      "keyword": {   
         "type": "keyword",
         "ignore_above": 256
      }
   }
}

對k4進行條件過濾時例如=,SelectDB On ES會將查詢轉換為ES的TermQuery。SQL過濾條件:

k4 = "SelectDB On ES"

轉換成ES的query DSL為:

"term" : { "k4": "SelectDB On ES"}

因為k4的第一字段類型為text,在數據導入的時候就會根據k4設置的分詞器(如果沒有設置,默認為standard分詞器)進行分詞處理得到selectdb、on、es三個Term,如下ES analyze API分析:

POST /_analyze{ "analyzer": "standard", "text": "SelectDB On ES"}

分詞的結果是:

{
   "tokens": [
      {
         "token": "selectdb",
         "start_offset": 0,
         "end_offset": 8,
         "type": "<ALPHANUM>",
         "position": 0
      },
      {
         "token": "on",
         "start_offset": 9,
         "end_offset": 11,
         "type": "<ALPHANUM>",
         "position": 1
      },
      {
         "token": "es",
         "start_offset": 12,
         "end_offset": 15,
         "type": "<ALPHANUM>",
         "position": 2
      }
   ]
}

查詢時使用的是:

"term" : { "k4": "SelectDB On ES"}

SelectDB On ES這個term匹配不到詞典中的任何term,不會返回任何結果。而在修改配置enable_keyword_sniff: true后,會自動將k4 = "SelectDB On ES"轉換成k4.keyword = "SelectDB On ES"來完全匹配SQL語義。轉換后的ES query DSL為:

"term" : { "k4.keyword": "SelectDB On ES"}

k4.keyword的類型是keyword,數據寫入ES中是一個完整的term,所以可以匹配。

開啟自動發現節點

通過設置"nodes_discovery" = "true",可以啟用自動發現節點功能。

當配置為true時,SelectDB將從ES找到所有可用的相關數據節點(在上面分配的分片)。如果ES數據節點的地址不能被SelectDB BE訪問,則設置為false。

說明

公有云ES服務通常采用負載均衡服務作為ES請求入口,無法直接訪問集群節點,需要將nodes_discovery設置為false

ES集群是否開啟HTTPS訪問模式

通過設置"ssl" = "true",可以開啟HTTPS訪問方式。

目前FE、BE實現方式為信任所有HTTPS請求。

時間類型字段使用建議

說明

僅適用ES外表,ES Catalog中自動映射日期類型為Date或Datetime。

在ES中,時間類型的字段是十分靈活,但是在ES外表中如果對時間類型字段的類型設置不當,則會造成過濾條件無法下推。

創建索引時,對時間類型格式的設置做最大程度的格式兼容:

 "dt": {
     "type": "date",
     "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
 }

在SelectDB中建立該字段時,一般建議設置為datedatetime,也可以設置為varchar類型,可使用如下SQL示例語句將過濾條件下推至ES:

SELECT * FROM doe WHERE k2 > '2020-06-21';

SELECT * FROM doe WHERE k2 < '2020-06-21 12:00:00'; 

SELECT * FROM doe WHERE k2 < 1593497011; 

SELECT * FROM doe WHERE k2 < now();

SELECT * FROM doe WHERE k2 < date_format(now(), '%Y-%m-%d');
重要
  • 在ES中如果不對時間類型的字段設置format, 默認的時間類型字段格式為:strict_date_optional_time||epoch_millis

  • 導入到ES的日期字段如果是時間戳,則需要轉換成ms單位,ES內部處理時間戳都是按照ms進行處理,否則ES外表會報錯。

獲取ES元數據字段_id

在ES中,在不指定_id的情況下導入文檔,ES會給每個文檔分配一個全局唯一的_id,即主鍵。 您也可以在導入時為文檔指定一個含有特殊業務意義的_id。如果需要在ES外表中獲取該字段值,建表時可以增加類型為varchar_id字段:

CREATE EXTERNAL TABLE `doe` (
  `_id` varchar COMMENT "",
  `city`  varchar COMMENT ""
) ENGINE=ELASTICSEARCH
PROPERTIES (
"hosts" = "http://127.0.0.1:8200",
"user" = "root",
"password" = "root",
"index" = "doe"
}

如果需要在ES Catalog中獲取該字段值,請設置"mapping_es_id" = "true"

重要
  • _id字段的過濾條件僅支持=in兩種。

  • _id字段必須為varchar類型。

附錄

SelectDB查詢ES原理如下。

+----------------------------------------------+
|                                              |
| SelectDB   +------------------+              |
|            |       FE         +--------------+-------+
|            |                  |  Request Shard Location
|            +--+-------------+-+              |       |
|               ^             ^                |       |
|               |             |                |       |
|  +-------------------+ +------------------+  |       |
|  |            |      | |    |             |  |       |
|  | +----------+----+ | | +--+-----------+ |  |       |
|  | |      BE       | | | |      BE      | |  |       |
|  | +---------------+ | | +--------------+ |  |       |
+----------------------------------------------+       |
   |        |          | |        |         |          |
   |        |          | |        |         |          |
   |    HTTP SCROLL    | |    HTTP SCROLL   |          |
+-----------+---------------------+------------+       |
|  |        v          | |        v         |  |       |
|  | +------+--------+ | | +------+-------+ |  |       |
|  | |               | | | |              | |  |       |
|  | |   DataNode    | | | |   DataNode   +<-----------+
|  | |               | | | |              | |  |       |
|  | |               +<--------------------------------+
|  | +---------------+ | | |--------------| |  |       |
|  +-------------------+ +------------------+  |       |
|   Same Physical Node                         |       |
|                                              |       |
|           +-----------------------+          |       |
|           |                       |          |       |
|           |      MasterNode       +<-----------------+
| ES        |                       |          |
|           +-----------------------+          |
+----------------------------------------------+
  1. FE會請求建表指定的主機,獲取所有節點的HTTP端口信息以及index的shard分布信息等,如果請求失敗會順序遍歷host列表直至成功或完全失敗。

  2. 查詢時,FE會根據FE得到的一些節點信息和index的元數據信息生成查詢計劃,并發給對應的BE節點。

  3. BE節點通過HTTP Scroll方式,流式地從ES index的每個分片中并發獲取_sourcedocvalue中的數據。

  4. SelectDB計算完結果后,返回給您。