2017-08-16 2 views
3

Hier ist der Code, den ich verwendet habe. Die DocumentModel-Klasse wird als elasticsearch-Dokument verwendet. Derzeit verwende ich URL als elasticsearch '_id' und erzeuge UUID für andere Feld documentId mit Java. Wenn ich versuche, ein Dokument mit diesem Code zu indexieren, aktualisiert es das Dokument, falls vorhanden, oder den Index, falls nicht vorhanden. Problem ist, wenn es Dokument aktualisiert, aktualisiert es auch documentId. Aber ich muss DocumentId nicht aktualisieren und vorhandene DocumentId verwenden. Welche Änderung sollte ich in diesem Code machen, um dies zu tun?Upserting ein elasticsearch Dokument

String uuid = UUID.randomUUID().toString(); 
         documentModel.setDocumentID(uuid); 
         String jsonForIndex = gson.toJson(documentModel); 
         IndexRequest indexRequest = new IndexRequest(indexName, typeName, documentModel.getId()); 
         indexRequest.source(jsonForIndex); 
         UpdateRequest updateRequest = new UpdateRequest(indexName, typeName, documentModel.getId()); 
         updateRequest.doc(jsonForUpdate); 
         updateRequest.upsert(indexRequest); 
         UpdateQuery updateQuery = new UpdateQueryBuilder().withIndexName(indexName).withType(typeName) 
           .withId(documentModel.getId()).withDoUpsert(true).withUpdateRequest(updateRequest).withIndexRequest(indexRequest).build(); 
elasticsearchTemplate.update(updateQuery).getId(); 

Antwort

0

Wenn Sie dies als Elasticsearch atomare Operation durchführen möchten, können Sie ES-Skript verwenden, um das DocumentID Feld zu verarbeiten und die bereits bestehenden halten.

Wenn Sie jedoch stattdessen Java verwenden möchten, können Sie einen Abruf durchführen, den neuen mit der Dokument-ID erstellen, falls vorhanden, und nur dann indexieren, wenn keine Versionsänderung vorliegt.

So etwas wie (Pseudocode):

old = client.prepareGet(indexName, type, uuid).get(); 

client.prepareIndex(indexName, type, uuid).setSource(<or the way you build it>).setVersion(old.getVersion() <if old is not null>).setRefresh(true).get(); 

Wenn eine gleichzeitige Transaktion das Dokument geändert Sie zu aktualisieren versuchten, es wird ein VersionConflictEngineException werfen. Sie können Spring Retry mit dieser Ausnahme verwenden und den get/index erneut ausführen (von let, wenn es fehlschlägt, wenn es das gewünschte Verhalten ist).

+0

Danke. Gibt es eine Möglichkeit, UpdateQuery mit IndexRequest und UpdateRequest zu verwenden (ohne prepareGet zu verwenden)? –

Verwandte Themen