迁移 Elastic Search:Elastic Search 7.x 利用模板做全局设置

2,671 阅读2分钟

Index templates | Elasticsearch Reference [7.8] | Elastic

  • There are two types of templates, index templates and component templates. Component templates are reusable building blocks that configure mappings, settings, and aliases. You use component templates to construct index templates, they aren’t directly applied to a set of indices. Index templates can contain a collection of component templates, as well as directly specify settings, mappings, and aliases.

索引模板分为两部分: index templates & component templates.

component templates

组件模板是可重用的构建块,用于配置映射、设置和别名

index templates

索引模板可以包含组件模板的集合,也可以直接指定设置、映射和别名

干的事情都是一样的,只不过 es 把模板进一步 [模块化] 了,component 是最小模板,index 可以 composed_of 多个 component,eg:

PUT _component_template/component_template1

PUT _component_template/component_template2

PUT _index_template/template_1
{
  ...
  "composed_of": ["component_template1", "other_component_template"],
  ...
}

我们要解决的是上次说到的 custom analyzer 的模板问题,所以这个问题,用屁股想想还是用 component 。

然而......

PUT /_component_template/template_1
{
  "template": {
    "settings" : {
        "number_of_shards" : 1
    }
  },
  "version": 123
}

{
  "error": "Incorrect HTTP method for uri [/_component_template/template_1?pretty] and method [PUT], allowed: [POST]",
  "status": 405
}

揉了揉眼睛,看错 API 了,看的是 current 版本的(当前7.8)我用的 7.4

看来暂时与组件无缘了,写下例子:

PUT _template/template_ngram_analyzer
{
  "index_patterns": ["*_v*", "*_*"], #定义哪些 index 会受到 template 的影响
  "settings": {
    "analysis": {
      "analyzer": {
        "ngram_one_word": {
          "type": "custom", 
          "tokenizer": "ngram", # 默认 min=1 max=2
          "filter": [
            "lowercase" 
          ]
        }
      }
    }
  }
}
  • 因为我们的 es index 有一些规则,所以 index_patterns 可以写的比较随意一些,先不写 stop filter,测试一下 ngram 是否好用

image

很顺利的建立了我们自定义分词器:ngram_one_word

image

查看一下 setting:

image

证实前期我对 nGram 分词的推测:

之前我是结合官网文档思考之后说过,我无法理解 min=1 max=1 能进行准确的匹配,业务模糊不要紧,我自己去测试一下:

  • 验证旧版本,果然有问题

image

  • 验证新版本

image

然而与旧版本几乎是一样的结果:

image

如果不追究当初写 custom analyzer : ngram 当时为啥这么写的具体场景和意义,其实本次迁移还是很成功的,撒花,掌声鼓励 !🎉👏

  • 后来我了解到当时针对 ngram 的用法,不是 match 查询,而是 match_phrase 查询,保证查询的顺序不变,这样就不会搜索 8899 查出 8930 了。

spring-data-elasticsearch 对 _template 的支持

首先,先搜索一些源码是否对 _template 做了支持,支持了最好,没支持自己实现,避免重复的轮子,ok,支持最好。

image

Spring Data 写法

//伪代码
public static final void createIndexTemp() {
		RestHighLevelClient client = EsClient.getClient();
		try {
			PutIndexTemplateRequest request = new PutIndexTemplateRequest("nGram_one_word")
			List<String> indexPatterns = new ArrayList<String>();
			indexPatterns.add("*_v*");
			indexPatterns.add("*_*");
			request.patterns(indexPatterns);
			
			 
			Map<String, Object> settings = new HashMap<>();
			
			// complate setting ......
			request.settings(settings);
			
			System.out.println(client.indices().putTemplate(request, RequestOptions.DEFAULT));
			
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			EsClient.close(client);
		}
	}

ES 写法:

//伪代码
public void createTemplate() {
        String templateName = "template_ngram_analyzer";
				String NGRAM_ONE_WORD = "{your string json ...}";
				PutIndexTemplateRequest request = new PutIndexTemplateRequest(templateName);
        request.source(NGRAM_ONE_WORD, XContentType.JSON);
        //强制创建,但不强制更新,省了个 exists
        request.create(true);
        elasticsearchRestTemplate.execute(client -> client.indices().putTemplate(request,RequestOptions.DEFAULT));
    }

删掉原来的 index template ,重新用 java client 测试一下 (create template 之前最好判断一下 exist)

image

github 归档 : github.com/pkwenda/Blo…