-1

My requirement is to create a spring boot application controller/service that calls elastic search reactive apis with out using traditional model and repositories. i need to pass dynamic json object to create documents in elastic search using spring controller and return dynamic json as a result for queries.

Could you please help me with below questions

  1. Does elastic search has reactive document apis for CRUDQ operations.if exists can we tie those to springboot application for CRUDQ operations without defining a model

  2. I did check few blogs where we can use ReactiveElasticsearchClient (Elasticsearch APIs centric) but takes a model as input to the api. can we create an api without providing model and pass dynamic json for create and return dynamic object as query results.

Thank you in advance!!!

ane
  • 101
  • 3
  • 10

1 Answers1

0

With the repository approach it may not be possible without the models. Having said that , the other way is to use the HTTP API using webflux to approach this problem.

As an example , I have set up a sample index with some data including an employee that matches this name

curl -XPOST "http://localhost:9200/_search" -H 'Content-Type: application/json' -d'{"query": {"match": {"name":"JohnSmith77067"}}}' |jq
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 3.205453,
    "hits": [
      {
        "_index": "sample",
        "_type": "employee",
        "_id": "KbxD6IEBCsN8USu280mF",
        "_score": 3.205453,
        "_source": {
          "id": null,
          "organization": {
            "id": 31,
            "name": "TestO31",
            "address": "Test Street No. 31"
          },
          "department": {
            "id": 3631,
            "name": "TestD3631"
          },
          "name": "JohnSmith77067",
          "age": 66,
          "position": "Developer"
        }
      }
    ]
  }
}

will try and emulate this through a free query run through reactive web client

@RestController
@RequestMapping("/employees")
public class EmployeeController {

    private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeController.class);
    private final WebClient client = WebClient.create();

    @PostMapping("/customselect")
    public Mono<String> generateMulti() throws URISyntaxException {
        return client.post().uri(new URI("http://localhost:9200/_search")).
                accept(MediaType.APPLICATION_JSON).
                header("Content-Type", "application/json").
                body(Mono.just("{\"query\": {\"match\": {\"name\":\"JohnSmith77067\"}}}"), String.class)
                .retrieve()
                .bodyToMono(String.class);

    }
}

starting the app up and then hitting the endpoint will return similar results You could pass a custom query in the body , but you get the idea of this.

[![Postman results][1]][1]

Having a repository based approach takes away all the boilerplate and provides a lot of goodies & error handling through config driven approaches. Having said that if that does not suit , for ES the way would be to use the raw HTTP API (there are many things you could attach to the web clients such as Auth , timeout etc that i have done) and then take it from there. Hope this helps a bit [1]: https://i.stack.imgur.com/FIAXR.png

Ramachandran.A.G
  • 4,788
  • 1
  • 12
  • 24
  • Additionally, the `_async` endpoint might fit your pattern better than the classic and sync `_search`: https://www.elastic.co/guide/en/elasticsearch/reference/current/async-search.html – xeraa Jul 10 '22 at 18:19
  • Thank you. Is it truly reactive non-blocking, handles back pressure with this approach. I believe the api calls are still synchronous. while _async appears to do multiple calls to get the results and needs to wait until the job is completed. Also not planning to use repository, i am using ReactiveElasticsearchClient (https://paolodedominicis.medium.com/reactive-spring-data-elasticsearch-with-spring-boot-dbcfdc9edb3d). in this blog i am not able to find an option to make myModel dynamic – ane Jul 11 '22 at 00:33
  • Just like any other client , this is responsible for interacting with a data store (ES in this case). Things like handling back-pressure depends throughout your pipeline , do you use a streaming framework , do you have a mechanism to buffer etc. Quite sure there may be options to use a WebClient when you have a velocity differential at source and targets. Have not used the ReactiveClient that you mentioned in spring , so ts quite hard to comment. In a true async scenario , you will call an async endpoint (as xeraa mentioned) , wait for the Future to complete or fail and then return – Ramachandran.A.G Jul 11 '22 at 02:35