diff --git a/api/src/main/java/com/rbmhtechnology/vind/api/Document.java b/api/src/main/java/com/rbmhtechnology/vind/api/Document.java index 7b3ba4f3..b181773e 100644 --- a/api/src/main/java/com/rbmhtechnology/vind/api/Document.java +++ b/api/src/main/java/com/rbmhtechnology/vind/api/Document.java @@ -13,6 +13,10 @@ */ public interface Document { + long VERSION_MUST_EXIST = 1; + long VERSION_DONT_CARE = 0; + long VERSION_MUST_NOT_EXIST = -1; + /** * Sets a value in a document field. If the field had already a value it is overwritten by the new value. * @param field Name of the field to set. @@ -301,6 +305,12 @@ public interface Document { */ String getType(); + /** + * Gets the document version. This field is used for optimistic concurrency. + * @return document version + */ + long getVersion(); + /** * Gets the document distance. * @return a distance for the document. diff --git a/api/src/main/java/com/rbmhtechnology/vind/model/DocumentFactory.java b/api/src/main/java/com/rbmhtechnology/vind/model/DocumentFactory.java index cfcdf5c3..e6ead58e 100644 --- a/api/src/main/java/com/rbmhtechnology/vind/model/DocumentFactory.java +++ b/api/src/main/java/com/rbmhtechnology/vind/model/DocumentFactory.java @@ -83,7 +83,33 @@ public Map> getFields() { * @return A {@link Document} with the configured {@link FieldDescriptor}. */ public Document createDoc(String id) { - return new DocumentImpl(id, this.type); + return createDoc(id, Document.VERSION_DONT_CARE); + } + + /** + * Creates an instance of a {@link Document} within the schema of the actual configuration of the factory. + * If a document with the same {@code id} already exists, indexing this document will fail. + * @param id Identification string of the new document. + * @return A {@link Document} with the configured {@link FieldDescriptor}. + */ + public Document createNewDoc(String id) { + return createDoc(id, Document.VERSION_MUST_NOT_EXIST); + } + + /** + * Creates an instance of a {@link Document} within the schema of the actual configuration of the factory with + * the provided document-version. + * + * @param id Identification string of the new document. + * @param docVersion the document version, or one of the pre-defined constants. + * @return A {@link Document} with the configured {@link FieldDescriptor}. + * + * @see Document#VERSION_DONT_CARE + * @see Document#VERSION_MUST_NOT_EXIST + * @see Document#VERSION_MUST_EXIST + */ + public Document createDoc(String id, long docVersion) { + return new DocumentImpl(id, this.type, docVersion); } /** @@ -128,14 +154,16 @@ class DocumentImpl implements Document { private final Set children = new HashSet<>(); private final String id; private final String type; + private final long version; private float score; private float distance; private Integer childCount; - private DocumentImpl(String id, String type) { + private DocumentImpl(String id, String type, long version) { //this.values.put(DocumentFactory.ID, id); this.id = id; this.type = type; + this.version = version; } /** @@ -660,6 +688,14 @@ public String getType() { return type; } + /** + * {@inheritDoc} + */ + @Override + public long getVersion() { + return version; + } + /** * {@inheritDoc} */ diff --git a/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrSearchServer.java b/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrSearchServer.java index 53ae2901..01f25058 100644 --- a/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrSearchServer.java +++ b/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrSearchServer.java @@ -290,6 +290,7 @@ private SolrInputDocument createInputDocument(Document doc) { document.addField(ID, doc.getId()); document.addField(TYPE, doc.getType()); + document.addField(VERSION, doc.getVersion()); return document; } diff --git a/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrUtils.java b/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrUtils.java index 76081a04..4b85f2a6 100644 --- a/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrUtils.java +++ b/backend/solr/src/main/java/com/rbmhtechnology/vind/solr/backend/SolrUtils.java @@ -756,6 +756,7 @@ public static Type getFromClass(Class clazz) { public static final String ID = "_id_"; public static final String TYPE = "_type_"; + public static final String VERSION = "_version_"; public static final String SCORE = "score"; public static final String DISTANCE = "_distance_"; public static final String TEXT = "text"; @@ -905,7 +906,9 @@ public static List buildResultList(SolrDocumentList results, Map { - Document document = factory.createDoc((String) result.getFieldValue(Fieldname.ID)); + final Document document = factory.createDoc(( + String) result.getFieldValue(Fieldname.ID), + (long) result.getFieldValue(Fieldname.VERSION)); if (childCounts != null) { document.setChildCount(ObjectUtils.defaultIfNull(childCounts.get(document.getId()), 0)); @@ -922,6 +925,7 @@ public static List buildResultList(SolrDocumentList results, Map !name.equals(Fieldname.ID)) .filter(name -> !name.equals(Fieldname.TYPE)) + .filter(name -> !name.equals(Fieldname.VERSION)) .filter(name -> !name.equals(Fieldname.SCORE)) .filter(name -> !name.equals(Fieldname.DISTANCE)) .forEach(name -> {