Delete a document from ElasticSearch index by id - elasticsearch

I have a document in elastic search.
I am trying to implement a method where I can specify a string id to delete a document from the index using NEST client.
This is the indexed doc that I want to delete:
"hits":[{"_index":"movies","_type":"list","_id":"100","_score":0.6349302, "_source" : {
"owner": "Bob",
"tags": "Bobita",
"title": "Movie clips of Bob"
}}
This is my C# code which doesn't delete the doc. It says id is NULL.
Uri localhost = new Uri("http://localhost:9200");
var setting = new ConnectionSettings(localhost);
setting.SetDefaultIndex("movies");
var client = new ElasticClient(setting);
IDeleteResponse resp = client.Delete("100");
if (!resp.Found)
{
logger.Error("Failed to delete index with id=100");
}
What am I missing?

I believe the issue here is that NEST cannot properly infer the Id property of your document because you are not specifying a type.
If possible, try this instead:
client.Delete<YourMovieType>("100");

Using NEST 7.x on Elasticsearch 7.0, following code works:
var x = _client.Delete<dynamic>(1);
(where 1 is '_id' value)
Use 'dynamic' if you have not defined the mapping. Else I would suggest to use the actual type.

await _elasticClient.DeleteAsync(new DeleteRequest(indexName, documentId));

Related

Update ElasticSearch document using Python requests

I am implementing ElasticSearch 7.1.1 in my application using Python requests library. I have successfully created a document in the elastic index using
r = requests.put(url, auth=awsauth, json=document, headers=headers)
However, while updating an existing document, the JSON body(containing to be updated values) that I pass to the method, replaces the original document. How do I overcome this? Thank you.
You could do the following:
document = {
"doc": {
"field_1": "value_1",
"field_2": "value_2"
},
"doc_as_upsert": True
}
...
r = requests.post(url, auth=awsauth, json=document, headers=headers)
It should be POST instead of PUT
You can update existing fields and also add new fields.
Refer the doc in the comment posted by Nishant Saini.

Field [_id] is a metadata field and cannot be added inside a document. Use the index API request parameters

I tried a bulk add as shown is your readme but instead I get this error:
"Field [_id] is a metadata field and cannot be added inside a document. Use the index API request parameters"
The model I'm trying to add is just a test model, and it's something like:
"_id" => "57028f25633db3473d0041c8"
The data is coming from a Mongo DB instance
I am using Windown 10, Phpstorm, xampp, Laravel 5.5, jenssegers/mongodb, elasticquent/elasticquent 1.0, Elasticsearch 6.0.0,
My code :
\App\Product::createIndex($shards = null, $replicas = null);
\App\Product::putMapping($ignoreConflicts = true);
\App\Product::addAllToIndex();
I had the same issue when I was redirecting the cloudwatch logs to ElasticSearch by terraform. This was resolved by adding filter_pattern for cloudwatch subscription filter (before it was empty).
resource "aws_cloudwatch_log_subscription_filter" "cloudwatch_logs_to_es" {
depends_on = [aws_lambda_permission.cloudwatch_allow]
name = var.clw_subscription_filter_name
log_group_name = aws_cloudwatch_log_group.auth0_log_group.name
filter_pattern = "[host, ident, authuser, date, request, status, bytes]"
destination_arn = aws_lambda_function.cwl_stream_lambda.arn
}

How to update a setting on the _doc type using elasticsearch.net/nest 6.x

Specifically what I'm trying to achieve through Elasticsearch.Net and NEST 6.x APIs is the example of setting dynamic=strict on the _doc type shown in this article using JSON.
The setting at the type level is also mentioned in the official docs
You can send this request with the high level client using
var client = new ElasticClient();
var putMappingResponse = client.Map<object>(m => m
.Index("testindex1")
.Type("_doc")
.Dynamic(DynamicMapping.Strict)
);
which will send the following request
PUT http://localhost:9200/testindex1/_doc/_mapping
{
"dynamic": "strict"
}
The end result will be that of strict behaviour for dynamic fields for the _doc type in the testindex1 index.
I dipped into the low-level client to effect this solution, whereas when I posted the question I was searching in the high level client.
using Nest; // C#
var pd = PostData.String("{ \"dynamic\": \"strict\" }");
var result = client.LowLevel.IndicesPutMappingPost<PutMappingResponse>(indexNm, "_doc", pd);
where the client variable is an ElasticClient instance.
and indexNm variable is a string containing "testindex1"
Results in
{
"testindex1": {
"aliases": {},
"mappings": {
"_doc": {
"dynamic": "strict",
where I see dynamic: strict has been added to the _doc type mapping as expected.

ElasticSearch NEST Executing raw Query DSL

I'm trying to create the simplest proxy possible in an API to execute searches on ElasticSearch nodes. The only reason for the proxy to be there is to "hide" the credentials and abstract ES from the API endpoint.
Using Nest.ElasticClient, is there a way to execute a raw string query?
Example query that is valid in vanilla ES:
{
"query": {
"fuzzy": { "title": "potato" }
}
}
In my API, I tried Deserializing the raw string into a SearchRequest, but it fails. I'm assuming it cannot deserialize the field:
var req = m_ElasticClient.Serializer.Deserialize<SearchRequest>(p_RequestBody);
var res = m_ElasticClient.Search<T>(req);
return m_ElasticClient.Serializer.SerializeToString(res);
System.InvalidCastException: Invalid cast from 'System.String' to 'Newtonsoft.Json.Linq.JObject'.
Is there a way to just forward the raw string query to ES and return the string response? I tried using the LowLevel.Search method without luck.
NEST does not support deserializing the short form of "field_name" : "your_value" of the Elasticsearch Query DSL, but it does support the long form "field_name" : { "value" : "your_value" }, so the following works
var client = new ElasticClient();
var json = #"{
""query"": {
""fuzzy"": {
""title"": {
""value"": ""potato""
}
}
}
}";
SearchRequest searchRequest;
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
searchRequest = client.Serializer.Deserialize<SearchRequest>(stream);
}
As Rob has answered, NEST also supports supplying a raw json string as a query
Yes, you can do this with NEST, check out the following
var searchResponse = client.Search<object>(s => s
.Type("type").Query(q => q.Raw(#"{""match_all"":{}}")));
Hope that helps.

Build dynamic queries with Spring Data MongoDB Criteria

I would like to run a bulk delete operation on a list of documents in MongoDB that have been selected by the user in the UI so I need to dynamically build a query that looks like the following (the or clause expands for every document selected):
{
$and: [
{
"contentType": "application/vnd.sometype"
},
{
$or: [
{
"metadata.name": "someName",
"metadata.version": "someVersion"
},
{
"metadata.name": "someOtherName",
"metadata.version": "someOtherVersion"
}
]
}
]
},
Fields: null,
Sort: null
Just now I'm using string concatenation to achieve this.
Is it possible to build this query with the Spring Data MongoDB Criteria Builder (org.springframework.data.mongodb.core.query.Criteria)?
Doesn't this work for you?
Criteria criteria = Criteria.where("contentType").is("application/vnd.sometype");
List<Criteria> docCriterias = new ArrayList<Criteria>(docs.size());
for (Document doc: docs) {
docCriterias.add(Criteria.where("metadata.name").is(doc.getName())
.and("metadata.version").is(doc.getVersion()));
}
criteria = criteria.orOperator(docCriterias.toArray(new Criteria[docs.size()]));
?
Here we need to build new query and embed the criteria to the built new query. And also, we have to create a list of criteria using some criteria for embed to the query. Here my example is providing a list of metadata and we don't know the name of parameter which will send for us. So, The solution is as given follow.
List<Criteria> criterias = new ArrayList<>();
for (MetaData metaData : newDoc.getMetaData()) {
Criteria dynamicCriteria = Criteria.where("metaData.key").is(metaData.getKey()).andOperator(Criteria.where("metaData.value").is(metaData.getValue()));
criterias.add(dynamicCriteria);
}
Criteria criteria = new Criteria().andOperator(criterias.toArray(new Criteria[criterias.size()]));
Query searchQuery = new Query(criteria);
List<Document> documents = mongoTemplate.find(searchQuery, Document.class);

Resources