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

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

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

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

NiFi: QueryElasticSearchHttp: Matching Objects with Expression Language?

I have a NiFi flow where I bring in some data through an API, which I easily route into ElasticSearch.
I have a second flow where I need to use the processor QueryElasticSearchHttp. Within that processor, I have a JSON query:
{
"query" : {
"bool" : {
"must" : [
{ "match" : { "Example1" : ${Example1} } },
{ "match" : { "ExampleCode" : ${ExampleCode} } }
]
}
}
}
I am trying to match the object Example1 and ExampleCode and return the whole column. I've tried to inject expression language into the query. Does not work, and I cannot find an example of how to match on an entire object.
I have tried to put quotation marks like so: "${}".
I get the error:
ERROR [Timer-Driven Process Thread-7] ...from Elasticsearch due to
Elasticsearch returned code 400 with message Bad Request, transferring
flow file to failure:
org.apache.nifi.processors.elasticsearch.UnretryableException:
Elasticsearch returned code 400 with message Bad Request
The Attributes are also correctly routed, and appear where they need to appear.
What is the correct way to format this? Thanks
You can try using the JsonQueryElasticsearch processor. A demo flow shown below:
Overall Flow
Start Step
Query ES Step
The JSON query
Store Result Step
The Controller Service
Output of Run:
$ cd /var/so_out
$ cat 17973351988502 | python -m json.tool
[
{
"_id": "o002",
"_index": "office",
"_score": 0.26742277,
"_source": {
"description": "Shows and events",
"name": "Tom",
"title": "Marketing Manager"
},
"_type": "doc"
}
]

Error while updating nested field

Hi i am using elasticsearch java API for updating a document with script. But i am getting below exception
Exception in thread "main" MapperParsingException[object mapping for [content] tried to parse field [content] as object, but found a concrete value]
at org.elasticsearch.index.mapper.DocumentParser.parseObject(DocumentParser.java:215)
at org.elasticsearch.index.mapper.DocumentParser.parseObjectOrField(DocumentParser.java:308)
at org.elasticsearch.index.mapper.DocumentParser.parseValue(DocumentParser.java:438)
at org.elasticsearch.index.mapper.DocumentParser.parseObject(DocumentParser.java:264)
at org.elasticsearch.index.mapper.DocumentParser.parseDocument(DocumentParser.java:124)
at org.elasticsearch.index.mapper.DocumentMapper.parse(DocumentMapper.java:309)
at org.elasticsearch.index.shard.IndexShard.prepareIndex(IndexShard.java:580)
at org.elasticsearch.index.shard.IndexShard.prepareIndexOnPrimary(IndexShard.java:559)
at org.elasticsearch.action.index.TransportIndexAction.prepareIndexOperationOnPrimary(TransportIndexAction.java:211)
at org.elasticsearch.action.index.TransportIndexAction.executeIndexRequestOnPrimary(TransportIndexAction.java:223)
at org.elasticsearch.action.index.TransportIndexAction.shardOperationOnPrimary(TransportIndexAction.java:157)
at org.elasticsearch.action.index.TransportIndexAction.shardOperationOnPrimary(TransportIndexAction.java:66)
at org.elasticsearch.action.support.replication.TransportReplicationAction$PrimaryPhase.doRun(TransportReplicationAction.java:657)
at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
at org.elasticsearch.action.support.replication.TransportReplicationAction$PrimaryOperationTransportHandler.messageReceived(TransportReplicationAction.java:287)
at org.elasticsearch.action.support.replication.TransportReplicationAction$PrimaryOperationTransportHandler.messageReceived(TransportReplicationAction.java:279)
at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:77)
at org.elasticsearch.transport.TransportService$4.doRun(TransportService.java:376)
at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Below is the existing document in the ES
{
"_index": "index1",
"_type": "type1",
"_id": "1",
"_version": 8,
"found": true,
"_source": {
"content": {
"contentId": 1,
"metadata": {
"title": "content one",
"duration": 4500
}
},
"custom": {
"field1": "value1"
}
}
}
I would like to update the "content" field as below
"content": {
"contentId": 1,
"metadata": {
"duration": 900
}
}
when i am updating with REST call (localhost:9200/index1/type1/1/_update), it is working fine. I am getting error in java API prepareUpdate.
I have 3 java classes.
DTO class has Content object
Content class has Metadata object and contentId as long
Metadata class has title (String) and duration(long).
Below is the code to update
Map<String, Object> params = new HashMap<>();
params.put("contentScript", dto.toString());
Script s = new Script("ctx._source.content=contentScript",ScriptType.INLINE,null,params);
UpdateResponse resp = client.prepareUpdate("index1", "type1", "1").setScript(s).setScriptedUpsert(true).get();
dto is object of DTO class and values are set accordingly.
Please help.
params.put("contentScript", dto.toString());
You are passing a string where it is expecting an object. The below code might help.
String script = "ctx._source.pete = jsonMap";
Map<String, Object> jsonMap = new ObjectMapper().readValue(json, HashMap.class);
Map<String, Object> params = ImmutableMap.of("jsonMap", jsonMap);
return new Script(script, ScriptService.ScriptType.INLINE, null, params);
https://discuss.elastic.co/t/how-to-update-nested-objects-in-elasticsearch-2-2-script-via-java-api/43135/2

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