博客 / 詳情

返回

Elasticsearch dynamic_templates 實戰 通用配置

動態模板 (Dynamic templates) 可以在創建 mapping 時,先定義好規則,當新字段滿足某條規則時,就會按照該規則的預先配置來創建字段。

前些年在使用 Elasticsearch 的時候,看到過 動態模板 (Dynamic templates) 相關的知識點,但並沒有想到如何在實際業務中應用,最近又看到這個知識點, 結合前些年被廣泛提及的 "低代碼平台",突然意識到如果有一個很簡單的增刪改查需求,前端通過推拽的方式組成頁面,後端如果使用 Elasticsearch 進行數據存儲,直接將前端傳遞過來的 JSON 數據進行存儲,至此需求就可以完成。 但是存在的問題是數據類型需要調整,便於後續的查詢和統計,那麼 動態模板 (Dynamic templates) 就可以解決這個問題,在創建索引的時候,約定好數據類型,後續根據約定生成不同的數據類型。

如下定義了一個較為通用的 dynamic_templates 配置,其中約定了 integer long date boolean scaled_float 等數據類型 (string_to_*),並且針對 string 類型的數據,修改了默認的分詞器規則為 IK 中文分詞器。

"date_detection": false 的配置,關閉了日期格式的自動檢測,避免識別錯誤, 形如 "createDate": "2000-01-01" 的格式,會不能按照如下的格式進行識別。
string_to_default_ik_string 部分,寫在最後部分説明在當前的配置中優先級最低,並且修改了剩餘的 字符串 類型的分詞方式 (IK)。
object_list_to_nested 部分,如果是以 List 結尾的話,約定 "type": "nested" ,避免數據被平鋪。

PUT http://localhost:9200/${indexName}

{
    "mappings": {
        "date_detection": false,
        "dynamic_templates": [
            {
                "string_to_integer": {
                    "match_mapping_type": "string",
                    "match": "*Int",
                    "mapping": {
                        "type": "integer"
                    }
                }
            },
            {
                "string_as_num": {
                    "match_mapping_type": "string",
                    "match": "*Num",
                    "mapping": {
                        "type": "integer"
                    }
                }
            },
            {
                "string_to_long": {
                    "match_mapping_type": "string",
                    "match": "*Long",
                    "mapping": {
                        "type": "long"
                    }
                }
            },
            {
                "string_to_date": {
                    "match_mapping_type": "string",
                    "match": "*Date",
                    "mapping": {
                        "type": "keyword",
                        "fields": {
                            "date": {
                                "type": "date",
                                "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
                            }
                        }
                    }
                }
            },
            {
                "string_to_time": {
                    "match_mapping_type": "string",
                    "match": "*Time",
                    "mapping": {
                        "type": "keyword",
                        "fields": {
                            "date": {
                                "type": "date",
                                "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
                            }
                        }
                    }
                }
            },
            {
                "string_to_bool": {
                    "match_mapping_type": "string",
                    "match": "*Bool",
                    "mapping": {
                        "type": "boolean"
                    }
                }
            },
            {
                "string_to_point_scaled_float": {
                    "match_mapping_type": "string",
                    "match": "*Point",
                    "mapping": {
                        "type": "scaled_float",
                        "scaling_factor": 100
                    }
                }
            },
            {
                "string_to_price_scaled_float": {
                    "match_mapping_type": "string",
                    "match": "*Price",
                    "mapping": {
                        "type": "scaled_float",
                        "scaling_factor": 100
                    }
                }
            },
            {
                "object_list_to_nested": {
                    "match_mapping_type": "object",
                    "match": "*List",
                    "mapping": {
                        "type": "nested"
                    }
                }
            },
            {
                "string_to_default_ik_string": {
                    "match_mapping_type": "string",
                    "match": "*",
                    "mapping": {
                        "type": "text",
                        "analyzer": "ik_max_word",
                        "search_analyzer": "ik_max_word",
                        "fields": {
                            "keyword": {
                                "type": "keyword"
                            }
                        }
                    }
                }
            }
        ]
    }
}

參考

  1. http://pap-docs.pap.net.cn/
  2. https://gitee.com/alexgaoyh/
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.