Запрос Spring Data Elasticsearch по структуре JSON - PullRequest
0 голосов
/ 16 сентября 2018

Я использую Spring Dataasticsearch, и намного проще связать код с реальным запросом JSONasticsearch, когда я использую аннотацию @Query, как в примерах в этой связанной ссылке:

https://www.programcreek.com/java-api-examples/index.php?api=org.springframework.data.elasticsearch.annotations.Query

Мне было интересно, есть ли способ сделать запрос по полному телу JSON через java-библиотекуasticsearch без аннотации. И.Е. в реализации метода или что-то. Это поможет мне разобрать подсветку в ответе и т.д ..

Спасибо за любую информацию.

Пояснение к комментариям: я использую spring-data -asticsearch 3.0.10.RELEASE с Elasticsearch 6. Так как spring-data -asticsearch пока не поддерживает RestHighLevelClient, я использую клиент TransportClient = новый PreBuiltTransportClient (elasticsearchSettings); подход при создании ElasticsearchTemplate: вернуть новый ElasticsearchTemplate (client ());

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

Вот еще один способ сделать это, но не использовать транспортный клиент.

Добавить эти зависимости к вашему pom.xml:

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-client</artifactId>
    <version>1.19</version>
    <scope>compile</scope>
</dependency>

Затем сделать это:

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;

Client client = new Client();
final WebResource r = client.resource("http://localhost:9200").path("/myindex/_search");
String requestJson = "{\"query\" : {\"match\" : {\"type\" : \"book\"} }}";
ClientResponse response = r.post(ClientResponse.class, requestJson);
String json = response.getEntity(String.class);

Gson gson = new GsonBuilder().setPrettyPrinting()
        .create();
Map map = gson.fromJson(json, Map.class);
System.out.println(gson.toJson(map));

// to convert to SearchResponse:
JsonXContentParser xContentParser = new JsonXContentParser(NamedXContentRegistry.EMPTY,
            new JsonFactory().createParser(json));
SearchResponse searchResponse = SearchResponse.fromXContent(xContentParser);

Пример вывода:

{
    "took": 9.0,
    "timed_out": false,
    "_shards": {
        "total": 5.0,
        "successful": 5.0,
        "failed": 0.0
    },
    "hits": {
        "total": 1.0,
        "max_score": 0.2876821,
        "hits": [
        {
            "_index": "myindex",
            "_type": "mydoc",
            "_id": "AWXp8gZjXyu6lA_2Kpi2",
            "_score": 0.2876821,
            "_source": {
                "title": "foobar",
                "type": "book"
            }
        }
        ]
    }
}
0 голосов
/ 18 сентября 2018

Я нашел один способ сделать это, но он требует, чтобы вы создали скрипт, который живет на узле Elastic. См. Файловые сценарии . Это не очень гибко, но попробуйте. Вот что нужно сделать.

Создайте файл с именем template_doctype.mustache и скопируйте его в $ELASTIC_HOME/config/scripts. Это сценарий, который вы можете адаптировать по мере необходимости. Перезапустите Elastic или подождите 60 секунд, пока он перезагрузится.

{
    "query" : {
        "match" : {
            "type" : "{{param_type}}"
        }
    }
}

Мои pom.xml зависимости:

<dependencies>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-elasticsearch</artifactId>
        <version>3.0.10.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>transport</artifactId>
        <version>5.5.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.2</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

(К вашему сведению, используя mvn dependency:tree, я обнаружил, что ваша версия spring-data-elasticsearch неявно использует версию 5.5 библиотеки ElasticSearch, даже если вы используете ElasticSearch 6.)

Создать фиктивный индекс:

curl -X PUT http://localhost:9200/myindex

Создайте пару документов, которые можно использовать для сопоставления, чтобы обеспечить работоспособность кода:

curl -X POST http://localhost:9200/myindex/mydoc -d '{"title":"foobar", "type":"book"}'
curl -X POST http://localhost:9200/myindex/mydoc -d '{"title":"fun", "type":"magazine"}'

Попробуйте выполнить запрос. Этот код должен возвращать один документ:

String clusterName = "my-application";
Settings elasticsearchSettings = Settings.builder().put("cluster.name", clusterName).build();
TransportClient client = new PreBuiltTransportClient(elasticsearchSettings)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9300));
Map<String, Object> template_params = new HashMap<>();

// Here is where you put parameters to your script.
template_params.put("param_type", "book");
SearchResponse sr = new SearchTemplateRequestBuilder(client)
        .setScript("template_doctype")  // this is where you specify what template to use
        .setScriptType(ScriptType.FILE)
        .setScriptParams(template_params)
        .setRequest(new SearchRequest())
        .get()
        .getResponse();

SearchHit[] results = sr.getHits().getHits();
for(SearchHit hit : results){

    String sourceAsString = hit.getSourceAsString();
    if (sourceAsString != null) {
        Gson gson = new GsonBuilder().setPrettyPrinting()
                .create();
        Map map = gson.fromJson(sourceAsString, Map.class);
        System.out.println( gson.toJson(map));
    }
}

Выход:

{
  "title": "foobar",
  "type": "book"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...