• Elasticsearch深入理解(十三)——Index更换字段类型的三种方式


    1.问题描述:

            需要将已有索引中的已有字段作为新的查询条件,需求中需要对该字段进行范围查询,当前字段为keyword类型的数字,此时发现查询所得结果与预期不符合。

    2.问题拆解:

    2.1发现问题:

    索引字段数据类型不合理

    2.2问题本质:

    需要将keyword类型的转换成数值类型,以便执行range query范围查询操作。因为keywork类型本质是字符串类型的一种,如果以keyword类型做字符串处理比的是首字符的ASCII码。

    2.3方案讨论:

    如何进行字段类型转换?

    对于三种方案来说,方案一贴合业务,方案二网络上也存在很多操作文档,方案三的文档较少在此给出操作步骤。

    方案一:重新建立索引,更正数据类型,重新导入数据

    特点:可以从根本上解决问题,但是不够灵活,所有依赖当前索引的服务需要重新上线将查询/写入指向新的索引。

    方案二:reindex+alias别名零停机方案

    特点:重新建立索引并且更正数据类型,reindex重新导入数据,使用alias别名的方式让用户无感知,依赖当前索引的服务也无需做任何操作。

    方案三:convert ingest预处理 + reindex结合

    特点:无需重新创建索引,哪个字段不满足就更改哪个字段

    3.convert ingest预处理 + reindex结合具体实现:

    3.1创建索引

    1. PUT student
    2. {
    3. "settings": {
    4. "number_of_shards": 1,
    5. "number_of_replicas": 0
    6. },
    7. "mappings": {
    8. "student":{
    9. "properties":{
    10. "obj":{
    11. "type":"object",
    12. "properties":{
    13. "id":{
    14. "type":"integer"
    15. },
    16. "name":{
    17. "type":"keyword"
    18. },
    19. "age":{
    20. "type":"keyword"
    21. }
    22. }
    23. }
    24. }
    25. }
    26. }
    27. }

    3.2写入数据

    1. POST student/student/1
    2. {
    3. "obj": [
    4. {
    5. "id": 1,
    6. "age": "21",
    7. "name": "项目1"
    8. },
    9. {
    10. "id": 2,
    11. "age": "51",
    12. "name": "项目2"
    13. }
    14. ]
    15. }
    16. POST student/student/2
    17. {
    18. "obj": [
    19. {
    20. "id": 1,
    21. "age": "21",
    22. "name": "项目1"
    23. },
    24. {
    25. "id": 2,
    26. "age": "51",
    27. "name": "项目2"
    28. }
    29. ]
    30. }
    31. POST student/student/3
    32. {
    33. "obj": [
    34. {
    35. "id": 1,
    36. "age": "21",
    37. "name": "项目1"
    38. },
    39. {
    40. "id": 2,
    41. "age": "51",
    42. "name": "项目2"
    43. }
    44. ]
    45. }

    3.3数据预处理convert

    1. PUT _ingest/pipeline/test_pipeline
    2. {
    3. "processors": [
    4. {
    5. "foreach": {
    6. "field": "obj",
    7. "processor": {
    8. "convert": {
    9. "field": "_ingest._value.age",
    10. "type": "integer",
    11. "ignore_failure": true
    12. }
    13. }
    14. }
    15. }
    16. ]
    17. }

    3.4数据reindex迁移

    1. POST _reindex
    2. {
    3. "source": {"index": "student"},
    4. "dest": {"index": "student1", "pipeline": "test_pipeline"}
    5. }

    3.5观察结果并分析

            查询student1的结果为,可以观察到age的数据类型已经转换为integer,反观student的查询结果,age的数据类型依旧为keyword,写入新的数据后观察查询结果依旧如此:

    1. {
    2. "took" : 0,
    3. "timed_out" : false,
    4. "_shards" : {
    5. "total" : 5,
    6. "successful" : 5,
    7. "skipped" : 0,
    8. "failed" : 0
    9. },
    10. "hits" : {
    11. "total" : 3,
    12. "max_score" : 1.0,
    13. "hits" : [
    14. {
    15. "_index" : "student1",
    16. "_type" : "student",
    17. "_id" : "2",
    18. "_score" : 1.0,
    19. "_source" : {
    20. "obj" : [
    21. {
    22. "name" : "项目1",
    23. "id" : 1,
    24. "age" : 21
    25. },
    26. {
    27. "name" : "项目2",
    28. "id" : 2,
    29. "age" : 51
    30. }
    31. ]
    32. }
    33. },
    34. {
    35. "_index" : "student1",
    36. "_type" : "student",
    37. "_id" : "1",
    38. "_score" : 1.0,
    39. "_source" : {
    40. "obj" : [
    41. {
    42. "name" : "项目1",
    43. "id" : 1,
    44. "age" : 21
    45. },
    46. {
    47. "name" : "项目2",
    48. "id" : 2,
    49. "age" : 51
    50. },
    51. {
    52. "name" : "项目3",
    53. "id" : 11,
    54. "age" : 11
    55. },
    56. {
    57. "name" : "项目4",
    58. "id" : 22,
    59. "age" : 31
    60. }
    61. ]
    62. }
    63. },
    64. {
    65. "_index" : "student1",
    66. "_type" : "student",
    67. "_id" : "3",
    68. "_score" : 1.0,
    69. "_source" : {
    70. "obj" : [
    71. {
    72. "name" : "项目1",
    73. "id" : 1,
    74. "age" : 21
    75. },
    76. {
    77. "name" : "项目2",
    78. "id" : 2,
    79. "age" : 51
    80. }
    81. ]
    82. }
    83. }
    84. ]
    85. }
    86. }

    4.总结:

    对于上述三种方案的取舍要取决于具体业务场景以及服务之间依赖关系是否紧密,如果调用方可以接受重新切换索引,可以酌情考虑方案一和方案三,方案一虽然操作起来较为繁琐,但原有的索引可以删除,节省内存空间。方案三虽然操作简单但是原有索引不可删除,若不计成本的情况下可以方案三更优。若调用方较多链路复杂,调用方不可接受上线切换索引则可以考虑方案二。

  • 相关阅读:
    流程设计的基本步骤
    一文快速带你了解 KMM 、 Compose 和 Flutter 的现状
    OpenCV实现人脸检测(Haar特征)
    Labelme安装以及使用教程
    MySQL入门指南4(查询进阶,外连接)
    2023.10.7 Java 创建线程的七种方法
    FPGA生成图像Modelsim仿真生成BMP图片保存显示
    中国人保为天能电力器具承保产品责任险,为消费者保驾护航!
    全国计算机三级嵌入式 - 题库 - 真题(含答案) - 未来教育 - 视频讲解 - 资料获取
    第三章:人工智能深度学习教程-基础神经网络(第五节-了解多层前馈网络)
  • 原文地址:https://blog.csdn.net/weixin_41860630/article/details/126485807