We have just upgraded from ES/Nest v5 to v 6.8. We have an api that does an upsert using a Painless script. The script checks to see that the lastUpdated date in the payload is greater than that in the indexed document, then it upserts the fields.
I have debugged, and I see that the items in the params Dictionary are correct in the Inline object. We create it with the following, with dictData being the Dictionary of properties on the doc.
return new InlineScript(script)
{
Lang = "painless",
Params = dictData,
};
We then create an UpdateRequest:
return new UpdateRequest<object, object>(FeedbackParentIndexAlias, FeedbackParentMainType, "feedbackparent|" + parentData.ParentFeedbackId.ToString())
{
RetryOnConflict = 1,
DetectNoop = true,
Upsert = lowerCaseParent,
Script = inlineScript,
Refresh = triggerRefresh ? Refresh.True : Refresh.False,
};
We then send this with:
var updateResponse = await this._nestClient.UpdateAsync<object, object>(upsertQuery, CancellationToken.None);
If I look at upsertQuery in the debugger, or I write to a string with either:
this._nestClient.SourceSerializer.SerializeToString(upsertQuery)
or
JsonConvert.SerializeObject(upsertQuery, Newtonsoft.Json.Formatting.None)
It shows the values for the properties inside of the engineeringwork array
{
"script": {
"inline": "def sf = new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss.SSS\");if(ctx._source.triagelastupdated != null && sf.parse(ctx._source.triagelastupdated).after(sf.parse(params.datetimecomparison))) { ctx.op = \"noop\"; } else {ctx._source.engineeringwork = params.engineeringwork;}",
"lang": "painless",
"params": {
"datetimecomparison": "2021-09-14T03:03:28.017Z",
"engineeringwork": [
{
"exampleInteger": 12345,
"exampleLink": "https://foo.com/id.456",
"exampleTitle": "This is an example"
}
],
"triagelastupdated": "2021-09-14T03:03:28.017Z"
},
"source": "def sf = new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss.SSS\");if(ctx._source.triagelastupdated != null && sf.parse(ctx._source.triagelastupdated).after(sf.parse(params.datetimecomparison))) { ctx.op = \"noop\"; } else {ctx._source.engineeringwork = params.engineeringwork;}"
},
"upsert": {
"This is": "The doc that would get indexed if there was no existing one"
}
}
When the upsert completes, the value indexed for engineeringwork is:
"engineeringwork": [
{
"exampleInteger": [],
"exampleLink": [],
"exampleTitle": []
}
Importantly, if I look at the Request that is returned back from the cluster shows that the Request sent was:
{
"script": {
"inline": "def sf = new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss.SSS\");if(ctx._source.triagelastupdated != null && sf.parse(ctx._source.triagelastupdated).after(sf.parse(params.datetimecomparison))) { ctx.op = \"noop\"; } else {ctx._source.engineeringwork = params.engineeringwork;}",
"lang": "painless",
"params": {
"datetimecomparison": "2021-09-14T03:03:28.017Z",
"engineeringwork": [
{
"exampleInteger": [],
"exampleLink": [],
"exampleTitle": []
}
],
"triagelastupdated": "2021-09-14T03:03:28.017Z"
},
"source": "def sf = new SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss.SSS\");if(ctx._source.triagelastupdated != null && sf.parse(ctx._source.triagelastupdated).after(sf.parse(params.datetimecomparison))) { ctx.op = \"noop\"; } else {ctx._source.engineeringwork = params.engineeringwork;}"
},
"upsert": {
"This is": "The doc that would get indexed if there was no existing one"
}
}
If I take the string representation (i.e. the serialized query) and run it from Kibana, it updates correctly.
It seems that params Dictionary that is being sent by the Nest client is not parsing the values correctly. I do always get the correct number of items, and each item has the correct property names, it is just the values that are missing.
The mapping for that field, is:
"engineeringwork" : {
"type" : "nested",
"include_in_parent" : true,
"include_in_all" : false,
"properties" : {
"exampleTitle" : {
"type" : "text",
"analyzer" : "case_insensitive",
"fielddata" : true
},
"exampleLink" : {
"type" : "text",
"analyzer" : "case_insensitive",
"fielddata" : true
},
"exampleInteger" : {
"type" : "integer"
}
}
}
BTW, I am using JsonNetSerializer on my Nest client:
ConnectionSettings settings = new ConnectionSettings(pool, new SecureElasticConnection(), sourceSerializer: JsonNetSerializer.Default);
Any help would be appreciated.
Thanks,
~john