Tipps für Java High Level REST-Clients

Dies ist der Artikel zum 11. Tag des Elastic Stack (Elasticsearch) Adventskalenders 2019.

Einführung

Auf Elasticsearch kann über Java-Apps mit dem "Java High Level REST Client" über http zugegriffen werden.

Zuvor wurde "TransportClient" verwendet, wurde jedoch in 8.0 eingestellt. Zum, "Java High Level REST-Client-Tipps" oder "Java Low Level REST Client "wird empfohlen.

Dieses Mal werde ich ein Anwendungsbeispiel vorstellen, das sich auf die Suche konzentriert (Such-API).

wichtiger Punkt

Beispiel) Elasticsearch(7.0) Java High Level REST(7.0) → OK Elasticsearch(7.0) Java High Level REST(6.8) → NG

Vorbereitung

Elasticsearch-Umgebung → Elastic Cloud Java8(JDK1.8.0)

Index "qiita" erstellen

PUT /qiita
{
  "mappings": {
    "properties": {
      "user":    { "type": "keyword" },  
      "post_date":  { "type": "date"  }, 
      "active":  { "type": "boolean"  },
      "message":   { "type": "text"  }     
    }
  }
}

POST qiita/_doc
{
    "user" : "qiita",
    "post_date" : "2019-12-11T00:10:30Z",
    "active":"false",
    "message" : "trying out High Level REST Client"
}

GET qiita/_search
...
      {
        "_index" : "qiita",
        "_type" : "_doc",
        "_id" : "yjDo5m4Bj4TzcUq3pmoX",
        "_score" : 1.0,
        "_source" : {
          "user" : "qiita",
          "post_date" : "2019-12-11T00:10:30Z",
          "active" : "false",
          "message" : "trying out High Level REST Client"
        }
      }
...

pon.xml

    <dependencies>
        ...
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>7.5.0</version>
        </dependency>
        ...
    </dependencies>

Erstellen Sie Clinent für die Verbindung

Grundsätzlich im Beispiel von Initialisierung kein Problem

RestHighLevelClient client = new RestHighLevelClient(
        RestClient.builder(
                new HttpHost("localhost", 9200, "http"),
                new HttpHost("localhost", 9201, "http")));

client.close();

Für elastische Wolke

Wenn Sie eine Authentifizierungsfunktion wie Elastic Cloud eingeführt haben, müssen Sie die folgenden Einstellungen vornehmen.

String username = "elastic";
String password = "pass";
String host = "host";
int port = 9243;
int nextPort = 9244;
String protocol = "https";


final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(
                AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));

RestClientBuilder client = RestClient.builder(
                new HttpHost(host, port, protocol),
                new HttpHost(host, nextPort, protocol))
                .setHttpClientConfigCallback((h) -> h.setDefaultCredentialsProvider(credentialsProvider));

RestHighLevelClient client = new RestHighLevelClient(client);

client.close();

Datenerfassung

Wenn Sie den zuvor erstellten Client verwenden, können Sie etwas Ähnliches wie "GET qiita / _search" erhalten.

try (RestHighLevelClient client = new RestHighLevelClient(client)) {

            SearchSourceBuilder searchBuilder = SearchSourceBuilder.searchSource();
            // quite*Sie können einen Platzhalter wie angeben
            SearchRequest request = new SearchRequest("qiita").source(searchBuilder);
            //Datenerfassung
            SearchHits hits = client.search(request, RequestOptions.DEFAULT).getHits();
            for(SearchHit hit : hits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();

          //Stellen Sie den Wert für jeden Datensatz ein
                String user = (String) sourceAsMap.get("user");
                String post_date = (String) sourceAsMap.get("post_date");
                String message = (String) sourceAsMap.get("message");
    
                System.out.println(String.format("user:%s data:%s message:%s",user , post_date, message));
            }
}catch (IOException io) {}

Referenz: Such-API

Größeneinstellung

Stellen Sie "Search Source Builder" ein Die Standardgröße ist nur 10

// default 10
SearchSourceBuilder searchBuilder = SearchSourceBuilder.searchSource();
searchBuilder.size(100);
            

Sortieren

Stellen Sie "Search Source Builder" ein Wechseln Sie mit Sortierreihenfolge zwischen ASC und DESC

SearchSourceBuilder searchBuilder = SearchSourceBuilder.searchSource();
searchBuilder.sort(new FieldSortBuilder("_id").order(SortOrder.DESC));

Suchabfrage (Filter)

Building Queries dreht sich alles um Hier sind einige einfache, die verwendet werden können (nicht alle wurden ausprobiert) Grundsätzlich auf "SearchSourceBuilder" setzen

Bereichsabfrage (Zeitraum angeben)

Erhalten von "2019-12-12T 00:10:30" bis "2019-12-13T 00:10:31" in japanischer Zeit

SearchSourceBuilder searchBuilder = SearchSourceBuilder.searchSource();

QueryBuilder query = QueryBuilders
       .rangeQuery("post_date")
       .from("2019-12-12T00:10:30")
       .to("2019-12-13T00:10:31")
       .timeZone("+09:00");

searchBuilder.query(query);

Seien Sie vorsichtig, wenn Sie Folgendes angeben Erhalten Sie von "2019-12-09T 00: 00: 00.000" bis "2019-12-13T 23: 59: 59.999"

QueryBuilder query = QueryBuilders
       .rangeQuery("post_date")
       .from("2019-12-12")
       .to("2019-12-13")
       .timeZone("+09:00");

searchBuilder.query(query);

So erhalten Sie Daten nur für 12 Tage:

"Include Lower" zum Einschließen von: true "IncludeUpper" zum Einschließen in: true

QueryBuilder query = QueryBuilders
       .rangeQuery("post_date")
       .from("2019-12-12")
       .to("2019-12-13")
    .includeLower(true)
    .includeUpper(false)
       .timeZone("+09:00");

searchBuilder.query(query);

Match Query Die Abfrage für die Volltextsuche ist unten

SearchSourceBuilder searchBuilder = SearchSourceBuilder.searchSource();

QueryBuilder query = QueryBuilders.matchQuery("message", "REST Level ");
QueryBuilder query = QueryBuilders.matchQuery("message", "Level REST");
QueryBuilder query = QueryBuilders.matchPhraseQuery("message", "REST Level");
//Da es sich um eine Phrasensuche handelt, werden 0 Elemente erfasst
QueryBuilder query = QueryBuilders.matchPhraseQuery("message", "Level REST");

searchBuilder.query(query);

Term Query Die Termabfrage, die nach exakter Übereinstimmung durchsucht wird, lautet wie folgt

QueryBuilder query = QueryBuilders.termQuery("user", "qiita");

Bool Query(AND OR NOT)

Elastic Elastic SQL Erläuterung
must AND
filter AND Ignoriere die Punktzahl
should OR
mustnot NOT

AND Entweder "muss" oder "filtern" ist akzeptabel

Ein Beispiel für "Filter" sieht so aus

SearchSourceBuilder searchBuilder = SearchSourceBuilder.searchSource();

BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
QueryBuilder query1 = QueryBuilders.matchQuery("message", "JAVA");
QueryBuilder query2 = QueryBuilders.matchQuery("message", "REST");
boolQuery.filter(query1);
boolQuery.filter(query2);

searchBuilder.query(boolQuery);

OR

BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
QueryBuilder query1 = QueryBuilders.matchQuery("message", "JAVA");
QueryBuilder query2 = QueryBuilders.matchQuery("message", "REST");
boolQuery.should(query1);
boolQuery.should(query2);

NOT

BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
QueryBuilder query = QueryBuilders.termQuery("user", "qiita");
boolQuery.mustNot(query);

Wie suche ich im JSON-Format?

Sie können es auch im JSON-Format erhalten, wie unten gezeigt. Search Template API

SearchTemplateRequest request = new SearchTemplateRequest();
request.setRequest(new SearchRequest("qiita"));

request.setScriptType(ScriptType.INLINE);
request.setScript(
                    "{" +
                            "  \"query\": { \"match\" : { \"{{field}}\" : \"{{value}}\" } }," +
                            "  \"size\" : \"{{size}}\"" +
                            "}");

Map<String, Object> scriptParams = new HashMap<>();
scriptParams.put("field", "message");
scriptParams.put("value", "REST");
scriptParams.put("size", 5);
request.setScriptParams(scriptParams);

SearchTemplateResponse response = client.searchTemplate(request, RequestOptions.DEFAULT);
SearchResponse searchResponse = response.getResponse();
SearchHit[] results = searchResponse.getHits().getHits();

Frozen indices Es kann ab 6.8.1 "Java High Level REST Client" verwendet werden. Beachten Sie, dass dies nicht berücksichtigt wird, wenn "Gefrorene Indizes" in Elastic Saerch implementiert sind.

How to Search Freeze Index using Java High Level REST Client

SearchRequest request = new SearchRequest("qiita").source(searchBuilder);
request.indicesOptions(IndicesOptions.fromOptions(
                true,
                true,
                true,
                false,
                request.indicesOptions().allowAliasesToMultipleIndices(),
                request.indicesOptions().forbidClosedIndices(),
                request.indicesOptions().ignoreAliases(),
                true //← Legen Sie fest, ob der eingefrorene Index hier als wahr durchsucht werden kann:Durchsuchbar
        ));

Referenzmaterial

Am Ende

Es gibt nur wenige japanische Artikel über "Java High Level REST Client", und ich lese oft englische und chinesische Artikel. Obwohl es größtenteils im Dokument geschrieben ist, scheint es nach dem Hinzufügen neuer Funktionen nicht von "Java High Level REST Client" unterstützt zu werden, sodass Sie möglicherweise die Quell- und Versionshinweise lesen müssen.

Morgen ist @ NAO_MK2.

Recommended Posts

Tipps für Java High Level REST-Clients
Migrieren Sie vom Transport Client zum Rest High Level Client
Java-Tipps, Tipps
Java-Tipps
Java mqtt Client
Java-Tipps - Modifikatoren der StataticUtility-Klasse
Java-Tipps - Zusammenfassung der Federausführung
[Java] Server Client Communication 1 (unvollendet)
[Java] Tipps zum Schreiben der Quelle