How can I query concrete Elasticsearch record by its __id? - elasticsearch

I have Elastic with Nest.
I have logs in elastic. I have no problems to query all by .client.Query(... But I'm having problems in getting one specific document by its __id using client.Get.
I'm using:
_el_client.Get<SystemLog>(id); // This does not work (_id = QUrLVXgB1uALlflB_-oF)
But object / record is not returned... What is the way to query a concrete elastic _id from Nest client?
This is the beginning of the document (just for the info).
"_index": "webapi-development-2021-03",
"_type": "_doc",
"_id": "QUrLVXgB1uALlflB_-oF",
"_version": 1,
"_score": null,
"_source": {
"#timestamp": "2021-03-21T18:18:55.2173785+01:00",
"level": "Information",
"messageTemplate": "{HostingRequestFinishedLog:l}",
// etc., etc.
Thx for your help...

Ok after many tests I find out solutions... I must say official DOCS sucks... This should be as startup examples.. Most common needs..
When using Get I need to specific concrete index not only part ending with *
Example:
GetResponse<SystemLog> result = _el_client.Get<SystemLog>(request.id, idx => idx.Index("webapi-development-2021-03"));
Require to build id for app containing __id + __index
Using search (easier but slower)
var response = _el_client.Search<SystemLog>(s => s
.Query(q => q
.Ids(i => i
.Values(request.id)
)
)
);

Related

Empty fields aren't shown directly in Elasticsearch?

I added an extra field called "title" with the Put Mapping API and then tried a normal search on my index with GET index_name/type/_search but the records don't show any field with "title" in it. Is it because the field has no content in it? If so how do I get fields with no content?
Thank you.
if you have _source enabled, elasticsearch will return the field value(whether empty or not), which you sent to it. as shown in below example.
{
"title" : "" // see empty value
}
And GET API on this doc-id returns below response
{
"_index": "newso",
"_type": "_doc",
"_id": "1",
"_version": 2,
"_seq_no": 1,
"_primary_term": 1,
"found": true,
"_source": {
"title": "" // same value is returned in response.
}
}
EDIT:- Based on #Val comment, If you are looking to find this newly added title field in old documents, where you didn't index this field, you will not be able to find it, As elasticsearch is schema-less, and doesn't enforce that you have to mandatory index a field. Also you can add/remove fields without updating mapping as its schemaless.
For this matter, even if you index a new document, after adding this title field in mapping, and don't include title field, then for that document again title field will not be returned.

Elasticsearch query to get results irrespective of spaces in search text

I am trying to fetch data from Elasticsearch matching from a field name. I have following two records
{
"_index": "sam_index",
"_type": "doc",
"_id": "key",
"_version": 1,
"_score": 2,
"_source": {
"name": "Sample Name"
}
}
and
{
"_index": "sam_index",
"_type": "doc",
"_id": "key1",
"_version": 1,
"_score": 2,
"_source": {
"name": "Sample Name"
}
}
When I try to search using texts like sam, sample, Sa, etc, I able fetch both records by using match_phrase_prefix query. The query I tried with match_phrase_prefix is
GET sam_index/doc/_search
{
"query": {
"match_phrase_prefix" : {
"name": "sample"
}
}
}
I am not able to fetch the records when I try to search with string samplen. I need search and get results irrespective of spaces between texts. How can I achieve this in Elasticsearch?
First, you need to understand how Elasticsearch works and why it gives the result and doesn't give the result.
ES works on the token match, Documents which you index in ES goes through the analysis process and creates and stores the tokens generated from this process to inverted index which is used for searching.
Now when you make a query then that query also generates the search tokens, these can be as it is in the search query in case of term query or tokens based on the analyzer defined on the search field in case of match query. Hence it's very important to understand the internals of your search query.
Also, it's very important to understand the mapping of your index, ES uses the standard analyzer by default on the text fields.
You can use the Explain API to understand the internals of the query like which search tokens are generated by your search query, how documents matched to it and on what basis score is calculated.
In your case, I created the name field as text, which uses the word joined analyzer explained in Ignore spaces in Elasticsearch and I was able to get the document which consists of sample name when searched for samplen.
Let us know if you also want to achieve the same and if it solves your issue.

Truncate and Index String values in Elasticsearch 2.3.x

I am running ES 2.3.3. I want to index a non-analyzed String but truncate it to a certain number of characters. The ignore_above property, according to the documentation, will NOT index a field above the provided value. I don't want that. I want to take say a field that could potentially be 30K long and truncate it to 10K long, but still be able to filter and sort on the 10K that is retained.
Is this possible in ES 2.3.3 or do I need to do this using Java prior to indexing a document.
I want to index a non-analyzed String but truncate it to a certain number of characters.
Technically it's possible with Update API and Upsert option, but, depending on your exact needs, it may not be very handy.
Let's say you want to index this document:
{
"name": "foofoofoofoo",
"age": 29
}
but you need to truncate name field so that it has only 5 characters. Using Update API, you'd have to execute a script:
POST http://localhost:9200/insert/test/1/_update
{
"script" : "ctx._source.name = ctx._source.name.substring(0,5);",
"scripted_upsert": true,
"upsert" : {
"name": "foofoofoofoo",
"age": 29
}
}
It means that, if ES does not find the document with given id (here id=1), it should index the document that is inside upsert element, and perform given script. So as you can see, it's rather inconvenient if you want to have automatically generated ids, as you have to provide the id in URI.
Result:
GET http://localhost:9200/insert/test/1
{
"_index": "insert",
"_type": "test",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"name": "foofo",
"age": 29
}
}

Remove Duplicate Fields Used for document_id Before Elasticsearch in Logstash

I wrote my own filter for Logstash and I'm trying to calculate my own document_id something like this:
docIdClean = "%d %s %s %s" % [ event["#timestamp"].to_f * 1000, event["type"], event["message"] ]
event["docId"] = Digest::MD5.hexdigest(docIdClean)
And the Logstash configuration looks like this:
output {
elasticsearch {
...
index => "analysis-%{+YYYY.MM.dd}"
document_id => "%{docId}"
template_name => "logstash_per_index"
}
}
The more or less minor downside is that all documents in Elasticsearch contain _id and docId holding the same value. Since docId is completely pointless as nobody searches for an MD5-hash I want to remove it, but I don't know how.
The docId has to exist when the event hits the output, otherwise the output can't refer to it. Therefore, I can't remove it beforehand. Since I can't remove it afterwards, the docId sits there occupying space.
I tried to set the event field _id, but that only causes an exception in Elasticsearch that the id of the document is different.
Maybe for explanation here one document:
{
"_index": "analysis-2014.09.16",
"_type": "access",
"_id": "022d9055423cdd0756b6cfa06886f866",
"_score": 1,
"_source": {
"#timestamp": "2014-09-16T19:36:31.000+02:00",
"type": "access",
"tags": [
"personalized"
],
"importDate": "2014/09/17",
"docId": "022d9055423cdd0756b6cfa06886f866"
}
}
EDIT:
This is about Logstash 1.3
There's nothing you can do about this in Logstash 1.4.
In Logstash 1.5, you can use #metadata fields, which are not passed to Elasticsearch.

Elasticsearch Nest, parent/child relationship

can you help me out to define a parent/child relationship using NESTclient for elasticsearch?
my code looks like this:
[ElasticType(Name = "type_properties", DateDetection = true,.....)]
public class Properties{....}
[ElasticType(Name = "type_sales", DateDetection = true, , ParentType = "type_properties")]
public class SalesHistory{....}
I defined the parentType, but I don't see this sales documents related to a parent property.
{
"_index": "testparentchild",
"_type": "type_sales",
"_id": "dVd1tUJ0SNyoiSer7sNA",
"_version": 1,
"_score": 1,
"_source": {
"salesRecId": 179504762,
"salesPrice": 150000,
"salesDate": "2003-04-07T00:00:00",
}
}
The attribute based mapping is deprecated since all the possible mapping possibilities cannot be expressed that way.
See
https://github.com/elasticsearch/elasticsearch-net/blob/master/src/Tests/Nest.Tests.Unit/Core/Map/FluentMappingFullExampleTests.cs
How to properly apply a mapping for your type.

Resources