ElasticSearch => How to updates with a partial document using update_by_query - elasticsearch

I want to update the data in my index whose cname is wang.
My index code is as follows:
PUT index_c
{
"mappings": {
"_doc" : {
"properties" : {
"cid" : {
"type" : "keyword"
},
"cname" : {
"type" : "keyword"
},
"cage" : {
"type" : "short"
},
"chome" : {
"type" : "text"
}
}
}
}
}
And my update request is as follows:
POST index_c/_update_by_query
{
"query" : {
"match": {
"cname": "wang"
}
},
"doc" : {
"cage" : "100",
"chome" : "china"
}
}
But I got an error like this:
{
"error": {
"root_cause": [
{
"type": "parsing_exception",
"reason": "Unknown key for a START_OBJECT in [doc].",
"line": 1,
"col": 43
}
],
"type": "parsing_exception",
"reason": "Unknown key for a START_OBJECT in [doc].",
"line": 1,
"col": 43
},
"status": 400
}
So I want to know how to implement this when using "update_by_query"

I think this will work for you just replace the doc part with script. if inline shows deprecated for you then just use source instead
POST index_c/_update_by_query
{
"query" : {
"match": {
"cname": "wang"
}
},
"script" : {
"inline" : "ctx._source.cage='100'; ctx._source.chome= 'china';",
"lang" : "painless"
}
}

Related

Not able to update mapping in elastic search

I have been trying to update my mapping but not able to do that. Majorly this question is related to updating the nested part. Suppose there is a field "Anand" which contains a field "hello"
{
"properties": {
"anand": {
"hello": {
"type": "short"
}
}
}
}
But I am getting the error
"error" : {
"root_cause" : [
{
"type" : "mapper_parsing_exception",
"reason" : "No type specified for field [anand]"
}
],
"type" : "mapper_parsing_exception",
"reason" : "No type specified for field [anand]"
},
"status" : 400
}
Current Mapping is
{
"anandschool" : {
"mappings" : {
"properties" : {
"anand" : {
"type" : "nested"
},
"doc" : {
"properties" : {
"properties" : {
"properties" : {
"shop_tier" : {
"type" : "long"
}
}
}
}
},
"message" : {
"type" : "byte"
},
"properties" : {
"properties" : {
"shop_tier" : {
"type" : "long"
},
"shop_type" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"shop" : {
"type" : "long"
}
}
}
}
}
I even created a nested type anand so that it can work
{
"properties": {
"anand": {
"type": "nested"
}
}
}
Self Answer
When updating mapping for nested things need to update properties of the nested field.
For above example update by
"properties": {
"anand": {
"properties":{
"hello": {
"type": "short"
}
}
}
}
}
THough This will not work inside a field which is nested.Ex if anand type was "nested", it would not work. If anyone knows solution for that let me know.

Bulk API error while indexing data into elasticsearch

I want to import some data into elasticsearch using bulk API. this is the mapping I have created using Kibana dev tools:
PUT /main-news-test-data
{
"mappings": {
"properties": {
"content": {
"type": "text"
},
"title": {
"type": "text"
},
"lead": {
"type": "text"
},
"agency": {
"type": "keyword"
},
"date_created": {
"type": "date"
},
"url": {
"type": "keyword"
},
"image": {
"type": "keyword"
},
"category": {
"type": "keyword"
},
"id":{
"type": "keyword"
}
}
}
}
and this is my bulk data:
{ "index" : { "_index" : "main-news-test-data", "_id" : "1" } }
{
"content":"\u0641\u0647\u06cc\u0645\u0647 \u062d\u0633\u0646\u200c\u0645\u06cc\u0631\u06cc: \u0627\u06af\u0631\u0686\u0647 \u062f\u0631 \u0647\u06cc\u0627\u0647\u0648\u06cc ",
"title":"\u06a9\u0627\u0631\u0647\u0627\u06cc \u0642\u0627\u0644\u06cc\u0628\u0627\u0641",
"lead":"\u062c\u0627\u0645\u0639\u0647 > \u0634\u0647\u0631\u06cc -.",
"agency":"13",
"date_created":1494518193,
"url":"http://www.khabaronline.ir/(X(1)S(bud4wg3ebzbxv51mj45iwjtp))/detail/663749/society/urban",
"image":"uploads/2017/05/11/1589793661.jpg",
"category":"15",
"id":"2981643"
}
{ "index" : { "_index" : "main-news-test-data", "_id" : "2" } }
{
....
but when I want to post data I receive this error:
{
"error" : {
"root_cause" : [
{
"type" : "illegal_argument_exception",
"reason" : "Malformed action/metadata line [3], expected START_OBJECT but found [VALUE_STRING]"
}
"status" : 400
}
what is the problem? I used both PowerShell and POST method in Kibana dev tools but I receive the same error in both.
The data should be specified in a single line like this:
{ "index" : { "_index" : "main-news-test-data", "_id" : "1" } }
{ "content":"\u0641\u0647","title":"\u06a9" }
Please refer this SO answer
Try this below format of bulk JSON. I have tested this bulk API request locally also, and now it's working perfectly fine:
{ "index" : { "_index" : "main-news-test-data", "_id" : "1" } }
{"content":"\u0641\u0647\u06cc\u0645\u0647 \u062d\u0633\u0646\u200c\u0645\u06cc\u0631\u06cc: \u0627\u06af\u0631\u0686\u0647 \u062f\u0631 \u0647\u06cc\u0627\u0647\u0648\u06cc ", "title":"\u06a9\u0627\u0631\u0647\u0627\u06cc \u0642\u0627\u0644\u06cc\u0628\u0627\u0641", "lead":"\u062c\u0627\u0645\u0639\u0647 > \u0634\u0647\u0631\u06cc -.", "agency":"13", "date_created":1494518193, "url":"http://www.khabaronline.ir/(X(1)S(bud4wg3ebzbxv51mj45iwjtp))/detail/663749/society/urban", "image":"uploads/2017/05/11/1589793661.jpg", "category":"15", "id":"2981643"}
Dont forget to add a new line at the end of your content.

Add date field and boolean with ? in name to existing Elasticsearch documents

We need to add two new fields to an existing ElasticSearch (7.9 oss) instance.
Field 1: Date Field
We want to add an optional date field. It shouldn't have a value upon creation.
How to do this with update_by_query?
Tried this:
POST orders/_update_by_query
{
"query": {
"match_all": {}
},
"script": {
"source": "ctx._source.new_d3_field",
"lang": "painless",
"type": "date",
"format": "yyyy/MM/dd HH:mm:ss"
}
}
Field 2: Boolean field with ? in name
We want to keep the ? so that it matches the other fields that we already have in ES.
Also worth noting that even removing the ? and doing the below the field doesn't appear to be a boolean.
Tried this:
POST orders/_update_by_query
{
"query": {
"match_all": {}
},
"script": {
"source": "ctx._source.new_b_field? = false",
"lang": "painless"
}
}
Which gave the error:
{
"error" : {
"root_cause" : [
{
"type" : "script_exception",
"reason" : "compile error",
"script_stack" : [
"ctx._source.new_b_field? = false",
" ^---- HERE"
],
"script" : "ctx._source.new_b_field? = false",
"lang" : "painless",
"position" : {
"offset" : 25,
"start" : 0,
"end" : 32
}
}
],
"type" : "script_exception",
"reason" : "compile error",
"script_stack" : [
"ctx._source.new_b_field? = false",
" ^---- HERE"
],
"script" : "ctx._source.new_b_field? = false",
"lang" : "painless",
"position" : {
"offset" : 25,
"start" : 0,
"end" : 32
},
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "invalid sequence of tokens near ['='].",
"caused_by" : {
"type" : "no_viable_alt_exception",
"reason" : null
}
}
},
"status" : 400
}
Also tried:
POST orders/_update_by_query?new_b_field%3F=false
Which gave:
{
"error" : {
"root_cause" : [
{
"type" : "illegal_argument_exception",
"reason" : "request [/orders/_update_by_query] contains unrecognized parameter: [new_b_field?]"
}
],
"type" : "illegal_argument_exception",
"reason" : "request [/orders/_update_by_query] contains unrecognized parameter: [new_b_field?]"
},
"status" : 400
}
If you want to add two new fields to an existing ElasticSearch index that don't have value upon creation you should update its mapping using Put mapping API
PUT /orders/_mapping
{
"properties": {
"new_d3_field": {
"type": "date",
"format": "yyyy/MM/dd HH:mm:ss"
},
"new_b_field?": {
"type": "boolean"
}
}
}
If you still want to use _update_by_query you should set an initial value, then the field will be added.
POST orders/_update_by_query?wait_for_completion=false&conflicts=proceed
{
"query": {
"match_all": {}
},
"script": {
"source": "ctx._source.new_d3_field=params.date;ctx._source.new_b_field = params.val",
"lang": "painless",
"params": {
"date": "1980/01/01",
"val": false
}
}
}
Update By Query API is used to update documents so I guess you can't add a field to your schema without updating at list one doc. what you can do is to set a dummy doc and update only this certain doc. Something like that:
POST orders/_update_by_query
{
"query": {
"match": {
"my-field":"my-value"
}
},
"script": {
"source": "ctx._source.new_d3_field=params.date;ctx._source.new_b_field = params.val",
"lang": "painless",
"params": {
"date": "1980/01/01",
"val": false
}
}
}

Upsert does not add new one when document doesn't exist (ElasticSearch)

I am creating new docs like this:
PUT test/_doc/1
{
"counter" : 1,
"tags" : "red"
}
Now I want to update or insert document whether or not it already exists:
POST test/_update/2
{
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
},
"upsert" : {
"counter" : 1
}
}
In my case, _doc=2 does not exist, for this I added upsert into the query so that it will be created automatically when the _doc does not exist.
Instead, I am getting this error message:
{
"error": {
"root_cause": [
{
"type": "invalid_type_name_exception",
"reason": "Document mapping type name can't start with '_', found: [_update]"
}
],
"type": "invalid_type_name_exception",
"reason": "Document mapping type name can't start with '_', found: [_update]"
},
"status": 400
}
Did I misunderstand how it works please?
UPDATE
Mapping:
PUT /test
{
"mappings": {
"type_name": {
"properties": {
"counter" : { "type" : "integer" },
"tags": { "type" : "text" }
}}},
"settings": {
"number_of_shards": 1
}
}
ElasticSearch version: "6.8.4"
try this
you were looking at 7.x documentation
this is the documentation for your version : https://www.elastic.co/guide/en/elasticsearch/reference/6.8/docs-update.html
POST test/type_name/2/_update
{
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
},
"upsert" : {
"counter" : 1
}
}

elasticsearch skip completion suggester duplicates

My elasticsearch current version is 6.0.1.
I'm using a completion suggester on my "suggest" field as follow:
GET my_index/_search
{
"suggest": {
"tag-suggest" : {
"prefix" : "black",
"completion" : {
"field" : "suggest",
"size" : 10,
"fuzzy" : {
"fuzziness" : 1
}
}
}
}
}
I'd like to skip duplicates in order to only retrieve unique suggestions.
According to elasticsearch documentation (https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html) I can achieve that by turning the option "skip_duplicates" to true:
GET my_index/_search
{
"suggest": {
"tag-suggest" : {
"prefix" : "black",
"completion" : {
"field" : "suggest",
"skip_duplicates": true,
"size" : 10,
"fuzzy" : {
"fuzziness" : 1
}
}
}
}
}
Unfortunately I'm getting the following error:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "[completion] unknown field [skip_duplicates], parser not found"
}
],
"type": "illegal_argument_exception",
"reason": "[completion] unknown field [skip_duplicates], parser not found"
},
"status": 400
}
Unfortunatelly skip_duplicates is not available in your version.
Please take a look here: https://www.elastic.co/guide/en/elasticsearch/reference/6.0/search-suggesters-completion.html
It was introduced in version 6.1: https://www.elastic.co/guide/en/elasticsearch/reference/6.1/search-suggesters-completion.html

Resources