Can we update/delete document from elastic search db without id - elasticsearch

I am new to Elastic Search db. With id property i am able to do update and delete but without id property (I mean another property of document which is unique) it is not working. Please let me know, can we do it or not.

I think what you are looking for is
Update by Query
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html
POST twitter/_update_by_query?conflicts=proceed
{
"query": {
"term": {
"user": "kimchy"
}
}
}
Delete by Query
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete-by-query.html
POST twitter/_delete_by_query
{
"query": {
"match": {
"message": "some message"
}
}
}

Here is the query to update
POST /indexName/typeName/_update_by_query
{
"query": {
"match": {
"name": "abc"
}
},
"script": {
"inline": "ctx._source.description = 'Updated description'"
}
}
Here is the query delete
POST /indexName/typeName/_delete_by_query
{
"query": {
"match": {
"name": "abc"
}
}
}

You can use _delete_by_query API.
_delete_by_query gets a snapshot of the index when it starts and deletes what it finds using internal versioning. That means that you’ll get a version conflict if the document changes between the time when the snapshot was taken and when the delete request is processed. When the versions match the document is deleted.
Code snippet.
POST twitter/_delete_by_query
{
"query": {
"match": {
"message": "some message"
}
}
}

Related

How to query in elasticsearch?

I am working on elastic search to fetch the record which contain string "bond"
{
"query": {
"match": {
"name": "Bond"
}
}
}
but I am getting empty array as a output. Though multiple records are present containing string "bold" , but i am getting empty hits. (hits:[])
How to solve this issue?
I am using same query for another index and its working but for index named as "all_colleges", its not working.
Its only returning the record when string is perfect match. i.e. "Bond" == "Bond"
You can try with fuzziness:
{
"query": {
"match": {
"name": {
"query": "Bond",
"fuzziness": "AUTO"
}
}
}
}
Actually there is many parameters you can add to get the results that you want in elastic search. Please check this link https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html
You can try this one
{
"query": {
"match": {
"name": {
"query": "Bond",
"fuzziness": "AUTO"
}
}
}
}
`

Create API keys on ElasticSearch with limited search capabilities

I want to create API keys on elasticsearch via POST _security/api_key API, I am able to create these but I want to limit search capability for the generated key which I am unable to do.
Essentially, what I want to achieve is let's say that all my records have a field like "username":"username1" or another one like "username":"username2" i.e. all the records will have a valid value for username field
Now what I want is to be able to create a key where I specify something like "username":"username2" which then gets appended to every search query made using that key as an AND case like if this key searches (/index_name/_search) for
{
"query": {
"match": {
"key_zz":"value_aa"
}
}
}
this query would actually be an AND of both of the below (i.e. if a record with this combination exists "key_zz":"value_aa" but the value for username is not username2, the API would not return that object)
{
"query": {
"match": {
"key_zz":"value_aa"
}
}
}
AND
{
"query": {
"must": {
"match" : {
"username":"username2"
}
}
}
}
I have tried creating the key with all of the following combinations:
"name": "key-name",
"role_descriptors": {
"role_name": {
"indices": [
{
"names": [
"index_name"
],
"privileges": [
"read"
],
"query": {
"match": {
"username": "value_custom"
}
}
}
]
}
}
}
In the query field, I have tried all the following combinations:
"query": {
"and": {
"username": "value_custom"
}
}
"query": {
"bool": {
"must": {
"match": {
"username": "value_custom"
}
}
}
}
"query": {
"bool": {
"must": {
"bool": {
"must": {
"match": {
"username": "value_custom"
}
}
}
}
}
}
But none of the above worked. Also, earlier the mapping type of username field was text but I then updated it to be keyword
In a nutshell, what I am trying to achieve is some kind of document level security. I know ElasticSearch has some kind of Document Level Security (https://www.elastic.co/guide/en/elastic-stack-overview/current/document-level-security.html) but in our architecture, we want to achieve this using API keys with restricted search capabilities. We are currently using Algolia and we were achieving this using the exact implementation I described above. ElasticSearch documentation has references for how to limit a role but not how to limit API keys. Need help to achieve this.
Also, I am using ElasticSearch v7
Some reference links :
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-role.html

How can I search in Has Parent Query

I've been trying to search through has parent query but I am not been able to do it as I can't find proper procedure to do it. For example I have roles table and I have user table and I am using 1 for administrator role and in user table I have an attribute with the name of user_role and I've record with user_role =1 how can I do mapping using has parent query and search accordingly.
Thanks,
Ali.
https://www.elastic.co/guide/en/elasticsearch/reference/5.5/mapping-parent-field.html
couldn't understand fully.
Let's take the mapping and sample data from https://www.elastic.co/guide/en/elasticsearch/reference/5.5/mapping-parent-field.html:
PUT my_index
{
"mappings": {
"my_parent": {},
"my_child": {
"_parent": {
"type": "my_parent"
}
}
}
}
PUT my_index/my_parent/1
{
"text": "This is a parent document"
}
PUT my_index/my_child/2?parent=1
{
"text": "This is a child document"
}
PUT my_index/my_child/3?parent=1&refresh=true
{
"text": "This is another child document"
}
The query on the same page, gets the single parent doc since both child documents are matching:
GET my_index/my_parent/_search
{
"query": {
"has_child": {
"type": "my_child",
"query": {
"match": {
"text": "child document"
}
}
}
}
}
With some slight modifications you'll be able to search on the has_parent:
GET my_index/my_child/_search
{
"query": {
"has_parent": {
"parent_type": "my_parent",
"query": {
"match": {
"text": "parent"
}
}
}
}
}
PS: This is changing quite a bit in 6.x. If possible I'd move to 6 now to avoid the upgrading pain later on.

how to i search in my whole index without giving fields in elasticsearch-kibana

GET my_production_productsd/_search
{
"query": {
"match_phrase_prefix": {
"ProductDescription": "women"
}
}
}
it gets results from only ProductDescription
Please take a look on _all field. It was deprecated in 6.0.0 version of ES mostly because of storage size. But you can still enable it. Maybe in your case it would not be a problem.
Example code:
GET /my_index/_search
{
"query": {
"match": {
"_all": "john smith 1970"
}
}
}

ElasticSearch Relationships

Hi Friends Please Help Me ...
I Have some doubt regarding the relationships in elastic search.
I will explain my doubt with the following example
Step 1:
I have created an index named "books" in elastic search
example.com:9200/books/
Step 2:
Then i created a type named 'author' and data inserted to it
POST example.com:9200/books/author/1
{
"fname" : "David","lname":"Thomas"
}
POST example.com:9200/books/author/2
{
"fname" : "Hamton","lname":"Vergo"
}
Step 3:
Then Created a mapping for another type 'authorbook' which is child of 'author'
POST example.com:9200/books/authorbook/_mapping
{"authorbook":{"_parent":{"type":"author"}}}
Step 4 :
Then i inserted data for authorbook
POST example.com:9200/books/authorbook/100?parent=1
{
"bookname" : "Bookname1"
}
POST example.com:9200/books/authorbook/200?parent=1
{
"bookname" : "Bookname2"
}
POST example.com:9200/books/authorbook/300?parent=2
{
"bookname" : "Bookname3"
}
step :5
Then i created a mapping for another type named 'publisher' , a child of authorbook
POST example.com:9200/books/publisher/_mapping
{"publisher":{"_parent":{"type":"authorbook"}}}
**Step 6:
Then i inserted data for publisher
POST example.com:9200/books/publisher/50?parent=200
{
"publname" : "publisher1"
}
POST example.com:9200/books/publisher/51?parent=200
{
"publname" : "publisher2"
}
POST example.com:9200/books/publisher/52?parent=100
{
"publname" : "publisher3"
}
Step 7
Now i have achieved in getting the 'authorbook' details by using a post request with following body
{
"query": {
"has_parent": {
"type": "author",
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"or": [
{
"term": {
"fname": "Hamton"
}
},
{
"term": {
"fname": "David"
}
}
]
}
}
}
}
}
}
My requirement is to get the publisher details also..how can achieve that? pls help..
Try this:
{
"query": {
"constant_score": {
"filter": {
"or": [
{
"has_parent": {
"type": "author",
"query": <your query above>
},
{
"has_parent": {
"type": "author"
"query": {
"constant_score": {
"filter": {
"has_parent": {
"type": "authorbook",
"query": <some query you need for the publishers>
}
}
}
}
}
}
]
}
}
}
This should return you authorbooks and publishers in the same query.
First tip: if you use "query": {"match_all": {}} in a filtered query you can also just use a constant_score query instead. Then you just have to provide the filter.
Second tip: When indexing a grandchild like publisher you better provide the routing query parameter as well (which should point to the id of the author). This makes sure children and grandchildren are stored in the same shard which makes lookup faster.
In general I would advice against a complicated relationship like this though. You can see that the query is hard to read and most likely hard to debug later on. Maybe keeping it simple could be better solution. Another idea is to have authorbook (or just book as a parent and publisher and author as normal (first level) children of the book. Reason is that author and publisher are not related, so you actually don't need this deep nesting.

Resources