How do you add an object to an array using scripts in ElasticSearch? - elasticsearch

I am trying to add an item to an array in one of my Elastic Search documents. I can do this for simple items, such as strings, but cannot work out now to add objects. Here is my current code:
POST /user_profiles/user_profile/12345/_update
{
"script" : {
"inline": "ctx._source.searches.add(params.search)",
"lang": "painless",
"params" : {
"search" : {
"test": "test2"
}
}
}
}
I am getting the following error:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "failed to parse [searches]"
}
],
"type": "mapper_parsing_exception",
"reason": "failed to parse [searches]",
"caused_by": {
"type": "illegal_state_exception",
"reason": "Can't get text on a START_OBJECT at 1:29"
}
},
"status": 400
}

I found the issue. It was unrelated to the query itself. The problem was that mappings for the index did not contain the additional fields.

Related

elasticsearch mapping issue: failed to parse field

I have this mapping
PUT /mytest
{
"mappings":{
"properties": {
"value": { "type": "object" }
}
}
}
When I insert this document
POST /mytest/_doc/4
{
"value": { "value": "test"}
}
I got the following error:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "failed to parse field [value.value] of type [long] in document with id '4'. Preview of field's value: 'test'"
}
],
"type": "mapper_parsing_exception",
"reason": "failed to parse field [value.value] of type [long] in document with id '4'. Preview of field's value: 'test'",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "For input string: \"test\""
}
},
"status": 400
}
I know the naming convention is bad, still, this is a valid JSON request, not sure why it doesn't allow it.
This error is telling you that you don't have a mapping for the property value within your value object property. The below example would property set the value.value property within your mytest index:
PUT mytest
{
"mappings": {
"properties": {
"value": {
"type": "object",
"properties": {
"value": {
"type": "text"
}
}
}
}
}
}
However, I don't think that's what your intention was. As a best practice, try following the Elastic Common Schema (ECS) for naming your index properties.

Script update with array method unique() causing error

I need to update array value with another array and then remove intersections, so I found this method 'unique()' for elasticsearch scripts, but it's causing error:
{
"error": {
"root_cause": [
{
"type": "remote_transport_exception",
"reason": "[probook][127.0.0.1:9300][indices:data/write/update[s]]"
}
],
"type": "illegal_argument_exception",
"reason": "failed to execute script",
"caused_by": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"ctx._source.arrFieldName = ctx._source.arrFieldName.unique();",
" ^---- HERE"
],
"script": "ctx._source.arrFieldName.addAll([111, 222, 333]);ctx._source.arrFieldName = ctx._source.arrFieldName.unique();ctx._source.arrFieldNameCount = ctx._source.arrFieldName.length",
"lang": "painless",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "dynamic method [java.util.ArrayList, unique/0] not found"
}
}
},
"status": 400
}
You should do it this way with distinct() instead of unique() for your inline painless script,
{
"script" : {
"inline": "ctx._source.arrFieldName=
ctx._source.arrFieldName.stream().distinct().sorted()
.collect(Collectors.toList())"
}
}

Upserts with a script gives me a null pointer exception

I am new to elastic search and I am testing the starter commands. I created an Index, added a document updated it with a simple update. now I am trying to make a scripted update with an upsert tag in the post request. I receiv a null pointr exception as shown below.
POST products/_update/1
{
"script" :"ctx._source.price += 5",
"upsert" : {
"price" : 1
}
}
I received the following instead of success
{
"error": {
"root_cause": [
{
"type": "remote_transport_exception",
"reason": "[DESKTOP-IGOE2EN][127.0.0.1:9300][indices:data/write/update[s]]"
}
],
"type": "illegal_argument_exception",
"reason": "failed to execute script",
"caused_by": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"ctx._source.price += 5",
" ^---- HERE"
],
"script": "ctx._source.price += 5",
"lang": "painless",
"caused_by": {
"type": "null_pointer_exception",
"reason": null
}
}
},
"status": 400
}
I think you should add a condition to check if the field (price) exists before accessing it by adding a if() condition:
POST products/_update/1
{
"script" :"if(ctx._source.price!= null) {ctx._source.price += 5"},
"upsert" : {
"price" : 1
}
}

Error message - Unable to filter min_docs_count

EDIT:
Answer below
getting always following error when trying any aggregated query.
Tried googling and different aggregation constructs.
Elasticsearch API Hosted as "Logs Data Platform" by OVH.
Request
{
"aggs" : {
"servers" : {
"filter" : { "term": { "servertype": "1" } },
"aggs" : {
"avg_price" : { "avg" : { "field" : "serveramount" } }
}
}
}
}
Error response
{
"error": {
"root_cause": [
{
"type": "parse_exception",
"reason": "Unable to filter min_docs_count"
}
],
"type": "parse_exception",
"reason": "Unable to filter min_docs_count",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "[size] parameter cannot be negative, found [-1]"
}
},
"status": 400
}
Stupid me ... size=0 was missing in the query parameter.

change elasticsearch mapping

I am trying to change the mapping using following code:
PUT /in_test/_mapping/keyword
{
"properties" : {
"term" : {
"type" : "text",
"index" : "not_analyzed"
}
}
}
But it is giving an error:
{
"error": {
"root_cause": [
{
"type": "remote_transport_exception",
"reason": "[tiebreaker-0000000000][172.17.0.24:19555][indices:admin/mapping/put]"
}
],
"type": "illegal_argument_exception",
"reason": "Could not convert [term.index] to boolean",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Failed to parse value [not_analyzed] as only [true] or [false] are allowed."
}
},
"status": 400
}
I also tried to recreate the index
by:
PUT /in_test
{
"mappings" : {
"keyword" : {
"properties" : {
"term" : {
"type" : "text",
"index" : "not_analyzed"
}
}
}
}
}
but I got:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "Failed to parse mapping [keyword]: Could not convert [term.index] to boolean"
}
],
"type": "mapper_parsing_exception",
"reason": "Failed to parse mapping [keyword]: Could not convert [term.index] to boolean",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Could not convert [term.index] to boolean",
"caused_by": {
"type": "illegal_argument_exception",
"reason": "Failed to parse value [not_analyzed] as only [true] or [false] are allowed."
}
}
},
"status": 400
}
I also tried to change the _type to keywords but it is still not working.
Basically, I want to search for exact match of string and for that I am referring to this:
https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_exact_values.html#_term_query_with_text
That documentation page is from Elasticsearch version 2.X (See at the top of the page), and is no longer correct for modern versions of Elasticsearch.
The error you're getting is because "index" now only accepts true or false, and refers to whether or not the property is indexed at all - Since you're searching by this property, you want it to be true (the default).
Instead, try setting the type to "keyword" and it won't be tokenized. https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-keyword-analyzer.html#_definition_5
PUT /in_test
{
"mappings" : {
"keyword" : {
"properties" : {
"term" : {
"type" : "keyword"
}
}
}
}
}

Resources