写点什么

由 Elasticsearch7.8 评分脚本引起的一个索引迁移解决方法

作者:北桥苏
  • 2023-05-13
    广东
  • 本文字数:1453 字

    阅读完需:约 5 分钟

前言:

​ 为了实践一下 ElasticSearch 的自定义相关度评分,使用了 Expression 脚本。但是在执行过程中却报错了,最后通过修改索引映射,添加别名和同步旧索引数据得以解决,所以以下也围绕这几项问题展开。

涉及知识:

索引映射修改


索引别名使用


重建索引


相关度评分

问题:

\1. 评分脚本执行报错。


(以下都是用 Kibana 的图形化开发工具测试 ES 的 API),当前索引是一个普通的产品数据,包括产品 ID,产品名称,产品别名,产品品类,价格,排序编号。下面只是想搜索某产品名,按照排序编号的相关度相乘的排序方式,但是却报错。 (注:_search 下取文档的值是 doc, 其他情况下 ctx)


GET products_new/_search{  "query": {    "function_score": {      "query": {        "match": {          "goods_name": 12        }      },      "script_score": {        "script": {          "lang": "expression",          "source": "_score * doc['goods_sort']"        }        }    }  }}
复制代码



\2. 修改索引映射报错。


​ 根据报错提示是因为脚本中执行的字段非数据,非日期和非地理位置类型,所以就需要对之前索引的字段类型进行修改。但是索引映射对字段的修改只能添加属性不能修改,mapper [goods_sort] of different type, current_type [keyword], merged_type [long],解决这个就需要重建索引。


索引重建

\1. 给旧索引添加别名。


POST /_aliases{  "actions": [    {      "add": {        "index": "products",        "alias": "products_alias"      }    }  ]}
复制代码


\2. 根据旧索引创建新字段类型的映射。


PUT products_new {  "mappings": {    "properties": {      "class_id": {        "type": "long"      },      "goods_name": {        "type": "text",        "analyzer": "ik_smart"      },      "goods_sort": {        "type": "long"      },      "id": {        "type": "long"      },      "price": {        "type": "text",        "fields": {          "keyword": {            "type": "keyword",            "ignore_above": 256            }        }      },      "single_goods_name": {        "type": "text",        "analyzer": "ik_max_word"      },      "state": {        "type": "long"      }    }  }}
复制代码


\3. 同步旧索引数据到新索引。


POST /_reindex{  "source": {    "index": "products"  },  "dest": {    "index": "products_new"  }}
复制代码


\4. 给新索引添加和旧索引相同的别名并移除旧索引别名。


POST /_aliases{  "actions": [    {      "add": {        "index": "products_new",        "alias": "products_alias"      },      "remove": {        "index": "products",        "alias": "products_alias"      }    }  ]}
复制代码


\5. 删除旧索引。


DELETE products{
}
复制代码


\6. 通过别名使用脚本评分。


GET products_alias/_search{  "query": {    "function_score": {      "query": {        "match": {          "goods_name": 12        }      },      "script_score": {        "script": {          "lang": "expression",          "source": "_score * doc['goods_sort']"        }        }    }  }}
复制代码



​ 为什么要给旧索引创建了别名,又后面移除再删除。那是因为修改了索引映射相当于进行了业务调整,为了不影响程序添加别名的情况下。等数据全部同步后再移除和删除就不会影响到业务了。



用户头像

北桥苏

关注

公众号:ZERO开发 2023-05-08 加入

专注后端实战技术分享,不限于PHP,Python,JavaScript, Java等语言,致力于给猿友们提供有价值,有干货的内容。

评论

发布
暂无评论
由Elasticsearch7.8评分脚本引起的一个索引迁移解决方法_elasticsearch_北桥苏_InfoQ写作社区