【问题标题】:Renaming fields to new index in Elasticsearch在 Elasticsearch 中将字段重命名为新索引
【发布时间】:2017-02-24 04:02:07
【问题描述】:

我有这个映射的索引:

curl -XPUT 'http://localhost:9200/origindex/_mapping/page' -d '
   {
    "page" : {
        "properties" : {
            "title" : {"type" : "text"},
            "body" : {"type" : "text"},
            "other": {"type": "text"}
        }
     }
   }'

在新索引中,我想将“title”复制到“title1”和“title2”,将“body”复制到“body1”和“body2”(忽略“other”),并将类型从“page ”到“articles_eng”。新索引有这个映射:

curl -XPUT 'http://localhost:9200/newindex/_mapping/articles_eng' -d '                             
{                                                                                                  
    "articles_eng" : {                                                                             
        "properties" : {                                                                           
            "title1" : {                                                                     
                 "type" : "text",                                                                  
                 "analyzer" : "my_analyzer1"                                                    
             },                                                                                     
            "title2" : {                                                                   
                 "type" : "text",                                                                  
                 "analyzer": "my_analyzer2"                                                    
             },                                                                                     
            "body1": {                                                                       
                "type" : "text",                                                                  
                "analyzer": "my_analyzer1"                                                     
            },                                                                                     
            "body2" : {                                                                     
                "type" : "text",                                                                  
                "analyzer": "my_analyzer2" 
            }                                                   
        }                                                                                      
    }                                                                                          
}'                                                                                              

通过查看this answerElasticsearch reindex docs 我想出了这样的事情:

curl -XPOST http://localhost:9200/_reindex -d '{                                                   
    "source": {                                                                                    
        "index": "origindex",                                                                          
        "type": "page",                                                                            
        "query": {                                                                                 
           "match_all": {}                                                                         
        },                                                                                         
        "_source": [ "title", "body" ]                                                             
    },                                                                                             
    "dest": {                                                                                      
        "index": "newindex"                                                                        
    },                                                                                             
    "script": {                                                                                    
        "inline": "ctx._type = \"articles_eng\"";                                                  
                  "ctx._title1 = ctx._source._title";                                         
                  "ctx._title2 = ctx._source._title";                                       
                  "ctx._body1 = ctx._source._body";                                          
                  "ctx._body2 = ctx._source._body"                                                                                                   
    }                                                                                              
}'

脚本行有问题。如果我只做第一行(更改文档类型),一切正常。如果我添加其余的行,我会收到错误

“[reindex] 解析字段 [script] 失败”

引起

“意外字符(';'(代码 59)):期待逗号分隔 [Source: 中的对象条目\n org.elasticsearch.transport.netty4.ByteBufStreamInput@37649463;线: 14、栏目:50]"

即使我可以通过多条语句解决问题,但只输入第二行就会出现错误

“添加到上下文 [title1] 的无效字段”}]

谁能帮帮我?看来这应该不是不可能的事。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    如果我只做第一行(更改文档类型),一切 工作正常。如果我添加其余的行,我会收到错误

    您不需要将所有内联语句放在双引号中,而是可以将所有内联脚本语句用分号(;)分隔并用双引号(")括起来,如下所示:

    "script": {
        "inline": "ctx._source.title1 = ctx._source.title; ctx._source.title2 = ctx._source.remove(\"title\");ctx._source.body1 = ctx._source.body; ctx._source.body2 = ctx._source.remove(\"body\");ctx._type=\"articles_eng\""
    }
    

    即使我可以用多个语句来解决问题,把 在第二行给了我错误

    您试图以错误的方式访问源字段。元数据字段(如_id, _type, _index ..)应以ctx._type/ctx._id 访问,而源字段(如您的情况下的title, body, other)应以ctx._source.title/ctx._source.body 访问。

    最后,您的 ReIndex 查询应该如下所示:

    POST _reindex
    {
      "source": {
        "index": "origindex",
        "_source": [ "title", "body" ]
      },
      "dest": {
        "index": "newindex"
      },
      "script": {
        "inline": "ctx._source.title1 = ctx._source.title; ctx._source.title2 = ctx._source.remove(\"title\");ctx._source.body1 = ctx._source.body; ctx._source.body2 = ctx._source.remove(\"body\");ctx._type=\"articles_eng\""
      }
    }
    

    希望这会有所帮助!

    【讨论】:

    • 谢谢你的回答,@avr!除了我的“title1”和“body1”字段始终为空之外,这几乎可以工作。我最终做了 "ctx._source.title1 = ctx._source.remove(\"title\"); ctx._source.title2 = ctx._source.title1" 等等,现在一切都很好。非常感谢您的帮助!
    • 我正在获取newindex 中所有字段的值。您在重新索引数据时是否发现任何错误?
    • 不,我没有。会不会是ES版本问题?我正在使用 5.0.2。
    • 我也在同一主要版本 5.2.0 上运行。出于调试目的,您可以将上面代码中的inline 行替换为以下行"inline": "ctx._source.title1 = ctx._source.title; ctx._source.title2 = ctx._source.title; ctx._source.body1 = ctx._source.body; ctx._source.body2 = ctx._source.body; ctx._type=\"articles_eng\"" 并运行api吗?
    • 这确实有效,尽管原始的“title”和“body”字段在新索引中,正如预期的那样。
    猜你喜欢
    • 1970-01-01
    • 2020-02-14
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多