https://github.com/olivere/elastic Version 5.x
The wiki documentation isn't really clear on how client.Update() works. It's needed to completely change a field and to modify arrays. i.e. in the example in the wiki documentation, how would one go about appending and removing tags to a tweet or changing a tweet's content? Also if a tweet was represented in go as a struct and I added a nested struct called "echo" which contains a foo of type int, content of type string and another type string array, how would one go about changing any of these fields using client.Update() if it's even possible?
In my personal example I have this function:
func UpdateEntryContent(eclient *elastic.Client, entryID string, newContent []rune) error{
ctx:=context.Background()
exists, err := eclient.IndexExists(ENTRY_INDEX).Do(ctx)
if err != nil {return err}
if !exists {return errors.New("Index does not exist")}
_, err = eclient.Update().Index(ENTRY_INDEX).Type(ENTRY_TYPE).Id(entryID).
Script("ctx._source.Content = newCont").
ScriptParams(map[string]interface{}{"newCont": newContent}).
Do(ctx)
if err != nil {return err}
return nil
}
But I get this following error when I try to compile:
cannot use "ctx._source.Content = newCont" (type string) as type *elastic.Script in argument to eclient.Update().Index(ENTRY_INDEX).Type(ENTRY_TYPE).Id(entryID).Script
eclient.Update().Index(ENTRY_INDEX).Type(ENTRY_TYPE).Id(entryID).Script("ctx._source.Content = newCont").ScriptParams undefined (type *elastic.UpdateService has no field or method ScriptParams)
Credit where it's due Gavin's answer put me on the right track. This is for another .Index
but the full function that acts as a generic single field update is as follows:
func UpdateUser(eclient *elastic.Client, userID string, field string, newContent interface{})error {
//CHANGES A SINGLE FIELD OF ES USER DOCUMENT(requires an elastic client pointer,
// the user DocID, the feild you wish to modify as a string,
// and what you want to change that field to as any type necessary)
//RETURN AN error IF SUCESSFUL error = nil
ctx := context.Background()
exists, err := eclient.IndexExists(USER_INDEX).Do(ctx)
if err != nil {return err}
if !exists {return errors.New("Index does not exist")}
_, err = eclient.Update().
Index(USER_INDEX).
Type(USER_TYPE).
Id(userID).
Doc(map[string]interface{}{field: newContent}).
Do(ctx)
return nil
}
You can change the .Index
, .Type
, and .Id
and it works with all fields and types as far as I can tell
The Script
method accepts a *elastic.Script
, not a string. The ScriptParams
method is also found on *elastic.Script
as Params
instead of being on *elastic.UpdateService
.
func UpdateEntryContent(eclient *elastic.Client, entryID string, newContent []rune) error{
ctx:=context.Background()
exists, err := eclient.IndexExists(ENTRY_INDEX).Do(ctx)
if err != nil {return err}
if !exists {return errors.New("Index does not exist")}
script := elastic.NewScript("ctx._source.Content = newCont").Params(map[string]interface{}{"newCont": newContent})
_, err = eclient.Update().Index(ENTRY_INDEX).Type(ENTRY_TYPE).Id(entryID).
Script(script).
Do(ctx)
if err != nil {return err}
return nil
}
You can see more information about the package with GoDoc or by looking through the source code.
The following code should resolve the issue
_, err = eclient.Update().Index(INDEX). Type(TYPE). Id(ID). Doc(map[string]interface{}{field: message}). Do(ctx)