开发者问题收集

更新 elasticsearch 中的嵌套对象

2018-10-29
16169

我对索引有以下映射

{
  "mappings": {
    "xxxxx": {
      "properties": {
        "ID": {
          "type": "text"
        },
        "pairs": {
          "type": "nested"
        },
        "xxxxx": {
          "type": "text"
        }
      }
    }
  }
}

pairs 字段是具有以下结构的对象数组

{
    "id": "",
    "Answer": "",
    "Question": []
}

我想检索特定的嵌套对象并更新它。我已尝试使用部分文档 / 脚本的 updateByQuery 方法,但无法更新

脚本

var theScript = {
    "inline": "ctx._source.Answer = 'Elastic search update Test'"
}

client.updateByQuery({
    index: 'sample',
    _source: false,
    body: {
        query: {
            bool: {
                must: [
                    {
                        "match": {
                            "ID": '2rXdCf5OM9g1ebPNFdZNqW'
                        }
                    },
                    {
                        "nested": {
                            "path": "pairs",
                            "query": {
                                "match": {
                                    "pairs.id": "c1vNGnnQLuk"
                                }
                            },
                            "inner_hits": {}
                        }
                    }
                ]
            }
        },
        "script": theScript
    }
},function(err, body){
    if(err){
        throw err;
    }
    console.log('body: ', body)
    console.log('data: ', body.hits.hits)
})

部分文档

client.updateByQuery({
    index: 'sample',
    _source: false,
    body: {
        query: {
            bool: {
                must: [
                    {
                        "match": {
                            "ID": '2rXdCf5OM9g1ebPNFdZNqW'
                        }
                    },
                    {
                        "nested": {
                            "path": "pairs",
                            "query": {
                                "match": {
                                    "pairs.id": "c1vNGnnQLuk"
                                }
                            },
                            "inner_hits": {}
                        }
                    }
                ]
            }
        },
       "doc": {
        "Answer": 'Elastic search update Test'
       }
    }
},function(err, body){
    if(err){
        throw err;
    }
    console.log('body: ', body)
    console.log('data: ', body.hits.hits)
})

我收到以下错误:

部分更新

Error: [parsing_exception] Unknown key for a START_OBJECT in [doc]., with { line=1 & col=191 }

脚本

Error: [illegal_argument_exception] [sample][conversation][AWa-p9zBTJHq-_gvo-Af] didn't store _source

注意 我理想情况下希望对此使用部分文档更新,因为嵌套对象有点复杂,并且不可能编写内联脚本

Elasticsearch 版本 - 5.6

更新

做这样的事情有效

{
    "script" : {
        "inline": "ctx._source.pairs= params.pairs",
        "lang": "painless",
        "params" : {
            "pairs" : [{...}, {...}, ...]
        }
    }
}

但这实质上意味着每次我更新时,我都会重写整个 pairs 字段(即使我只更新数组中的一个对象) - 这对我来说看起来并不理想,还是可以?

3个回答

有一个页面包含有关嵌套类型管理的快速教程: 如何管理 Elasticsearch 文档中的嵌套对象 。它解释了如何添加、删除和编辑嵌套对象。

Edgar Chavolla
2020-02-24

没有用于更新特定嵌套文档的语法。您只能指定嵌套字段值,它会更新所有嵌套文档。无论如何,ES 都会通过部分更新重新索引文档。

您可以使用父子文档来实现这一点,但需要付出一些代价。如果您有这么多嵌套记录,那么它可能更适合您的情况。

Demi
2018-10-29

以下是一些可能有帮助的内容。附加示例查询

{
  "script": {
    "source": "ctx._source.nested_field.forEach(item -> item.nested_field2 = params.new_value)",
    "lang": "painless",
    "params": {
      "new_value": 100
    }
  },
  "query": {
    "match_all": {}
  }
}

我的映射是这样的

"mappings": {
        "properties": {
            "field1": {
                "type": "text"
            },
            "field2": {
                "type": "integer"
            },
            "nested_field": {
                "type": "nested",
                "properties": {
                    "nested_field1": {
                        "type": "text"
                    },
                    "nested_field2": {
                        "type": "integer"
                    },
                     "nested_field3": {
                        "type": "text"
                    }
                }
            }
        }
    }

希望它有所帮助 :)

Abhishek Bairagi
2023-09-21