es 创建动态索引(二)

作者: 良人与我 | 来源:发表于2019-06-15 15:24 被阅读0次

上一篇文章
es 创建动态索引(一) ,通过el表达式 修改 @Document 里 indexName 值,实现 es 动态索引。
https://www.jianshu.com/p/5d170ce6777d

后来使用时候发现如果实体类上有注解@Field
例如

@Field(type = FieldType.Text, analyzer = "ik_max_word")

springboot 启动时候创建的mapping为:

{
    "type": "text",
    "analyzer": "ik_max_word"
}

而这种动态的方式为创建的mapping为:

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

不一样,所以就想看看 启动时候是怎么创建的。使用同样的方式创建就可以。

AbstractElasticsearchRepository.java 中,
构造函数初始时候会去判断要不要创建index和mapping
这个值在@Document中,默认值为true


image.png

如果要创建就调用 创建index 和 put mapping方法

    public AbstractElasticsearchRepository(ElasticsearchEntityInformation<T, ID> metadata,
            ElasticsearchOperations elasticsearchOperations) {
        this(elasticsearchOperations);

        Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!");

        this.entityInformation = metadata;
        setEntityClass(this.entityInformation.getJavaType());
        try {
            if (createIndexAndMapping()) {
                createIndex();
                putMapping();
            }
        } catch (ElasticsearchException exception) {
            LOGGER.error("failed to load elasticsearch nodes : " + exception.getDetailedMessage());
        }
    }

    private void createIndex() {
        elasticsearchOperations.createIndex(getEntityClass());
    }

    private void putMapping() {
        elasticsearchOperations.putMapping(getEntityClass());
    }

而创建和映射是调用elasticsearchOperations 的方法实现的
而它的实现类 即是ElasticsearchTemplate
时序图如下:


image.png

所以我们可以在保存数据时候,判断索引是否存在,不存在创建和设置mapping

    @Test
    public void testsave() throws InterruptedException {
        for (int i = 0; i < 6 ; i++) {
            Thread.sleep(1000*10);
            Student student = new Student();
            student.setName("name:"+i);
            student.setAge(12);
            student.setDesc("hello world");
            student.setCreatDate(new Date());
            student.setArea("xian");

            if(!elasticsearchTemplate.indexExists(student.getClass())){
                System.out.println("create index at "+DateUtil.now());
                elasticsearchTemplate.createIndex(student.getClass());
                elasticsearchTemplate.putMapping(student.getClass());
            }
            System.out.println("save doc at "+DateUtil.now());
            studentService.save(student);
            System.out.println("-----save-----");
        }
    }

亲测 ok 了。

而之前的时间粒度为秒 来创建动态索引 太细了。
可能索引创建和mapping ok 了,但是保存时候 到了下一秒,es 自己就会去创建 。
所以为了测试 将时间细分到 分来测试。

@Data
@Document(
        indexName = "student-" + "#{ T(com.river.es.entity.Student).dateStr() }",
        //indexName = "student",

        type = "student",
        shards = 2,
        replicas = 1, refreshInterval = "-1")
public class Student {

    @Id
    private String id;

    @Field(type = FieldType.Keyword)
    private String name;

    @Field(type = FieldType.Integer)
    private Integer age;

    private String desc;

    /**
     * 采购区域
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String area;


    @Field(type = FieldType.Date,
            format = DateFormat.custom,
            pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'",timezone="GMT+8")
    private Date creatDate;

    public static String dateStr()
    {
        String rst ;
        rst = DateUtil.now().replace(" ","-");
        return rst.substring(0,16);
    }
}

测试结果如下,索引 和 mapping都没问题。

{
  "student-2019-06-15-14:56": {
    "mappings": {
      "student": {
        "properties": {
          "age": {
            "type": "integer"
          },
          "area": {
            "type": "text",
            "analyzer": "ik_max_word"
          },
          "creatDate": {
            "type": "date",
            "format": "yyyy-MM-dd'T'HH:mm:ss'Z'"
          },
          "desc": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "name": {
            "type": "keyword"
          }
        }
      }
    }
  },
  "student-2019-06-15-14:55": {
    "mappings": {
      "student": {
        "properties": {
          "age": {
            "type": "integer"
          },
          "area": {
            "type": "text",
            "analyzer": "ik_max_word"
          },
          "creatDate": {
            "type": "date",
            "format": "yyyy-MM-dd'T'HH:mm:ss'Z'"
          },
          "desc": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "name": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

相关文章

网友评论

    本文标题:es 创建动态索引(二)

    本文链接:https://www.haomeiwen.com/subject/sbebfctx.html