Elasticsearch Nest, parent/child relationship - elasticsearch

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.

Related

How can I query concrete Elasticsearch record by its __id?

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)
)
)
);

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 document found false

I am trying to access a document with _id.
I recently dumped an index from remote server to my local server.
Here's how I am trying to get the document:
GET http://localhost:9200/dmap_product_match/dmap_product_match/ZA2JeGsBsz9baORiZSkN
And in response:
{
"_index": "dmap_product_match",
"_type": "dmap_product_match",
"_id": "ZA2JeGsBsz9baORiZSkN",
"found": false
}
But requesting for the document as a query body returns the document:
GET http://localhost:9200/dmap_product_match/_search
{
"_source": ["s_item_name","r_item_name","human_verdict"],
"query": {
"term":{
"_id": "ZA2JeGsBsz9baORiZSkN"
}
}
}
EDIT: elasticsearch v7.0.0.
ElasticSearch is not finding the document you are asking for because the document type is not well defined in the request.
The api to fetch documents has the following format:
GET http://<host>:<port>/<index>/<type>/<docId>
According to the request you post, you are looking for the document with the id ZA2JeGsBsz9baORiZSkN in the index dmap_product_match and type dmap_product_match.
Your request should be something like:
GET http://localhost:9200/dmap_product_match/_doc/ZA2JeGsBsz9baORiZSkN

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.

How to reverse all the strings inside an array in an elasticsearch document with a groovy script?

I have an elasticsearch document
{
"_index": "testindex",
"_type": "testtype",
"_id": "doc1",
"_version": 1,
"found": true,
"_source": {
"array": [
"abc",
"def",
"ghi"
]
}
}
How do I reverse all the strings inside the array in the document? I tried using update api with the following script
temp = []; for(String item : ctx._source.array) temp << item.reverse(); ctx._source.array = temp;
Update api in java :
new org.elasticsearch.action.update.UpdateRequest(index, type, docId).script(script);
I am getting an exception like method call not allowed inside the script.
Bulk request failure, id: [doc4], message: ElasticsearchIllegalArgumentException[failed to execute script]; nested: GroovyScriptCompilationException[MultipleCompilationErrorsException[startup failed:
General error during canonicalization: Method calls not allowed on [java.lang.String]
try this
temp=[];
ctx._source.array.each{
it -> temp.add(it.reverse())
}
ctx._source.array = temp

Resources