ElasticSearch: Replace a field value - elasticsearch

Is there anyway to "replace a field value" by another one using a more or less straightforward process?
Example:
PUT twitter/tweet/{1...n}
{
"user" : "kimchy"
}
I want to replace user field of documents where "user is kimchy" setting a new value.
I figure out that the most straightforward way to get that is:
getting all documents,
change them,
save them again.
I'm looking forward to knowing if there's another a bit more elegant way.
Example: Update field = "new value" on documents where field is "value". Is there anyway to perform this single command on ES?

Related

Grafana variable: Return all Elastic documents when selecting "All" and the attribute might be an empty list

Take the following Lucene query:
provision_org.keyword:$provision_org
If $provision_org has the value "hello", the query returns all documents where provision_org (a list) contains the item "hello". So far so good.
If $provision_org has the value "*", the query returns all documents where provision_org (a list) contains an element.
Is there any value that I could assign to $provision_org so that all documents are returned, even those where provision_org is an empty list?
The reason I want this value is to set it as the "Custom All value" in the Grafana (multi-value) variable. Obviously what I want is to have an "All" option that effectively results in ignoring that particular variable. (I'm not really certain that the "Custom All value" is the correct way to do that.)
This might help:
* OR (NOT _exists_:provision_org.keyword)
Or you can use Ad hoc filter, but way to use it is quite different from variable

MongoDB ruby driver update single field

https://docs.mongodb.com/ruby-driver/v2.14/tutorials/ruby-driver-crud-operations/#updating
I' been doing this
videos.find({"id": "c024f2bd"}).update_one({"title": "this is testing"})
When i look over the database it replace the entire document with just this field, my other field were all gone and empty. How can i update just single field? i've read the document it doesn't seem to have option parameter where i can define update field only don't replace.
You should use $set. Try this:
videos.update_one({"id": "c024f2bd"}, {"$set": {"title": "this is testing"}})

how to update the nested data of elastic search?

i am new to elastic search. i have successfully setup elastic-search server and implemented ES package in laravel. now i can add data to elastic search, but the problem is how can i update a nested item value in a row?. i have added a screen shot of my data structure here a link!
Now how can i update comment_id 1 with my desired content?
In your case it will be a little problematic.
You should be aware of the way elasticsearch index arrays.
So in your case you will get something like this:
{
.
.
"comments":{
"id": [1,2,3],
"comment": ["this is comment1", "this is comment2", "this is comment3"]
}
}
So you loose the correlation between "id" and "comment".
If you like to keep this correlation you will need to define "comments" as "nested" in your mappings. look here.
In order to update your nested document you will probebly need to use scripted update.
If you will need to update a specific comment in the array, you can write a script that find it and replace it, or you can read the whole array, edit it and override the current array.

Cost of adding field mapping in elasticsearch type

I have a use-case, where I have got a set of predefined fields and also need to support adding dynamic fields to ElasticSearch with some basic searching on them. I am able to achieve this using dynamic template mapping. However, the frequency of adding such dynamic fields is quite high.
Consider the this ES document for the Event type:
{
"name":"Youth Conference",
"venue":"Ahmedabad",
"date":"10/01/2015",
"organizer":"Invincible",
"extensions":{
"about": {
"vision":"Visualizes the image of an ideal Country. ",
"mission":"Encapsulates the gravity of the top reformative solutions for betterment of Country."
}
// Any thing can go here..
}
}
In the example above, each event document may have any unknown/new fields. Hence, for every such new dynamic field introduced, ES will update the mapping of the type. My concern is what is the cost of adding new field mapping in the existing type?
I am planning to separate out all dynamic mappings(inside extensions) from Event type by introducing another type, say EventExtensions and using parent/child relationship to map it with Event type. I believe this may limit the cost(if any) of adding dynamic fields frequently to the type. However, to my knowledge, using parent/child relationship will need more memory.
The first thing to remember here is that field is per index and not per type.
So wherever you add new fields , it would be made in the same index. Be it , in another type or as parent or child.
So decoupling the new fields to another type but same index is not going to make any change.
Second field addition is not that very expensive thing. I know people who uses 1000 of fields and are good with it. That being said , there should be a tab on number of field so that it wont go out to crazy numbers.
Here we have multiple approaches to solve the problem
1) Lets assume that the new field data need not be exactly searchable. In this case , you can deserialize the entire JSON as a string and add it to a field. Also make sure this field is not indexed. This way you can search based on other fields but then on retrieval of the document , get the information that was deserialized.
2) Lets say the new field looks like this
{
"newInfo1" : "log Of Info",
"newInfo2" : "A lot more info"
}
Instead of this , you can use
{
"newInfo" : [
{
"fieldName" : "newInfo1",
"fieldValue" : "log Of Info"
},
{
"fieldName" : "newInfo2",
"fieldValue" : "A lot more info"
}
]
}
This way , fields wont increase. But then to make field level specific search , like give me all documents with filedName as newInfo2 and having the word more in it , you will need to make newInfo field nested.
Hope this helps.

What indexes are created when indexing a document in elasticsearch

If I create a first document of it's type, or put a mapping, is an index created for each field?
Obviously if i set "index" to "analyzed" or "not analyzed" the field is indexed.
Is there a way to store a field so it can be retrieved but never searched by? I imagine this will save a lot of space? If I set this to "no" will this save space?
Will I still be able to search by this, just take more time, or will this be totally unsearchable?
Is there a way to make a field indexed after some documents are inserted and I change my mind?
For example, I might have a mapping:
{
"book":{"properties":{
"title":{"type":"string", "index":"not_analyzed"},
"shelf":{"type":"long","index":"no"}
}}}
so I want to be able to search by title, but also retrieve the shelf the book is on
index:no will indeed not create an index for that field, so that saves some space. Once you've done that you can't search for that particular field anymore.
Perhaps also useful in this context is to know aboutthe _source field, which is returned by default and includes all fields you've stored. http://www.elasticsearch.org/guide/reference/mapping/source-field/
As to your second question:
you can't change your mind halfway. When you want to index a particular field later on you have to reindex the documents.
That's why you may want to reconsider setting index:no, etc. In fact a good strategy to begin is to don't define a schema for fields at all, unless you're 100% sure you need a non-default analyzer for a particular field for instance. Otherwise ES will use generally usable defaults.

Resources