I am trying to do an updateByQuery with the javascript api, and am using painless. Before running updateByQuery, I first update the index's mapping by adding in the following:
await putMapping(elastic, index, {
properties: {
maps: {
type: 'nested',
properties: {
...Object.assign(
{},
...maps.map((m) => ({
[m.id]: {
type: 'text',
fields: {
raw: {
type: 'keyword',
},
},
},
}))
),
},
},
},
});
which basically says, allow documents to have a field called maps
that will contain n number of fields, that will be a text / keyword type. So I'm expecting to have something like ctx._source.maps.A
as a text or keyword type eventually.
Once the mapping is updated, I then want to leverage updateByQuery to update documents that are returned from various queries so that they have values in the _source.maps[mapId]
space.
My painless script in the updateByQuery looks something like this:
if (!ctx._source.containsKey('maps')) {
def m = new HashMap();
ctx._source['maps'] = m;
}
if (!ctx._source.maps.containsKey('${mapId}')) {
ctx._source.maps['${mapId}'] = new ArrayList();
}
if(!ctx._source.maps.${mapId}.contains('myKeywordIWantToAdd')){
ctx._source.maps.${mapId}.add('myKeywordIWantToAdd');
}
When I run this updateByQuery, and then run a search using the same query used in updateByQuery, and then look at the returned results, I can see that the _source is updated. However, those fields are not searchable. If I try to run an exists
query on maps.A
for example, nothing is returned. If I do an exists
query on just maps
nothing returns either. If I do a term search on maps.A
for a value I KNOW exists in that list, nothing returns. I've tried refreshing and flushing the index with no luck.
My best guess is that I should not be using a HashMap
or a ArrayList
to build out new portions of my document, but I'm not really sure. Any guidance would be greatly appreciated. Thank you.