Added version support to mget and get apis, that only will perform the get operation if the version of the document to be fetched matches with the provided version.
Both get and mget apis now support the following additional parameters: `version` and `version_type`. Closes #3404
This commit is contained in:
parent
3b2a9fc86b
commit
a9dd3c9756
|
@ -276,7 +276,6 @@ public class BulkRequest extends ActionRequest<BulkRequest> {
|
||||||
String opType = null;
|
String opType = null;
|
||||||
long version = Versions.MATCH_ANY;
|
long version = Versions.MATCH_ANY;
|
||||||
VersionType versionType = VersionType.INTERNAL;
|
VersionType versionType = VersionType.INTERNAL;
|
||||||
String percolate = null;
|
|
||||||
int retryOnConflict = 0;
|
int retryOnConflict = 0;
|
||||||
|
|
||||||
// at this stage, next token can either be END_OBJECT (and use default index and type, with auto generated id)
|
// at this stage, next token can either be END_OBJECT (and use default index and type, with auto generated id)
|
||||||
|
|
|
@ -26,6 +26,8 @@ import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.Required;
|
import org.elasticsearch.common.Required;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
import org.elasticsearch.common.lucene.uid.Versions;
|
||||||
|
import org.elasticsearch.index.VersionType;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -53,6 +55,9 @@ public class GetRequest extends SingleShardOperationRequest<GetRequest> {
|
||||||
|
|
||||||
Boolean realtime;
|
Boolean realtime;
|
||||||
|
|
||||||
|
private VersionType versionType = VersionType.INTERNAL;
|
||||||
|
private long version = Versions.MATCH_ANY;
|
||||||
|
|
||||||
GetRequest() {
|
GetRequest() {
|
||||||
type = "_all";
|
type = "_all";
|
||||||
}
|
}
|
||||||
|
@ -197,6 +202,31 @@ public class GetRequest extends SingleShardOperationRequest<GetRequest> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the version, which will cause the get operation to only be performed if a matching
|
||||||
|
* version exists and no changes happened on the doc since then.
|
||||||
|
*/
|
||||||
|
public long version() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GetRequest version(long version) {
|
||||||
|
this.version = version;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the versioning type. Defaults to {@link org.elasticsearch.index.VersionType#INTERNAL}.
|
||||||
|
*/
|
||||||
|
public GetRequest versionType(VersionType versionType) {
|
||||||
|
this.versionType = versionType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VersionType versionType() {
|
||||||
|
return this.versionType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readFrom(StreamInput in) throws IOException {
|
public void readFrom(StreamInput in) throws IOException {
|
||||||
super.readFrom(in);
|
super.readFrom(in);
|
||||||
|
@ -218,6 +248,8 @@ public class GetRequest extends SingleShardOperationRequest<GetRequest> {
|
||||||
} else if (realtime == 1) {
|
} else if (realtime == 1) {
|
||||||
this.realtime = true;
|
this.realtime = true;
|
||||||
}
|
}
|
||||||
|
this.versionType = VersionType.fromValue(in.readByte());
|
||||||
|
this.version = in.readVLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -244,6 +276,9 @@ public class GetRequest extends SingleShardOperationRequest<GetRequest> {
|
||||||
} else {
|
} else {
|
||||||
out.writeByte((byte) 1);
|
out.writeByte((byte) 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out.writeByte(versionType.getValue());
|
||||||
|
out.writeVLong(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.action.support.single.shard.SingleShardOperationRequest
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.client.internal.InternalClient;
|
import org.elasticsearch.client.internal.InternalClient;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
|
import org.elasticsearch.index.VersionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A get document action request builder.
|
* A get document action request builder.
|
||||||
|
@ -107,6 +108,23 @@ public class GetRequestBuilder extends SingleShardOperationRequestBuilder<GetReq
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the version, which will cause the get operation to only be performed if a matching
|
||||||
|
* version exists and no changes happened on the doc since then.
|
||||||
|
*/
|
||||||
|
public GetRequestBuilder setVersion(long version) {
|
||||||
|
request.version(version);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the versioning type. Defaults to {@link org.elasticsearch.index.VersionType#INTERNAL}.
|
||||||
|
*/
|
||||||
|
public GetRequestBuilder setVersionType(VersionType versionType) {
|
||||||
|
request.versionType(versionType);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doExecute(ActionListener<GetResponse> listener) {
|
protected void doExecute(ActionListener<GetResponse> listener) {
|
||||||
((Client) client).get(request, listener);
|
((Client) client).get(request, listener);
|
||||||
|
|
|
@ -29,8 +29,10 @@ import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.io.stream.Streamable;
|
import org.elasticsearch.common.io.stream.Streamable;
|
||||||
|
import org.elasticsearch.common.lucene.uid.Versions;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.index.VersionType;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -47,6 +49,8 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> {
|
||||||
private String id;
|
private String id;
|
||||||
private String routing;
|
private String routing;
|
||||||
private String[] fields;
|
private String[] fields;
|
||||||
|
private long version = Versions.MATCH_ANY;
|
||||||
|
private VersionType versionType = VersionType.INTERNAL;
|
||||||
|
|
||||||
Item() {
|
Item() {
|
||||||
|
|
||||||
|
@ -110,6 +114,24 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> {
|
||||||
return this.fields;
|
return this.fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long version() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item version(long version) {
|
||||||
|
this.version = version;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VersionType versionType() {
|
||||||
|
return versionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item versionType(VersionType versionType) {
|
||||||
|
this.versionType = versionType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public static Item readItem(StreamInput in) throws IOException {
|
public static Item readItem(StreamInput in) throws IOException {
|
||||||
Item item = new Item();
|
Item item = new Item();
|
||||||
item.readFrom(in);
|
item.readFrom(in);
|
||||||
|
@ -129,6 +151,8 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> {
|
||||||
fields[i] = in.readString();
|
fields[i] = in.readString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
version = in.readVLong();
|
||||||
|
versionType = VersionType.fromValue(in.readByte());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -145,6 +169,8 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> {
|
||||||
out.writeString(field);
|
out.writeString(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out.writeVLong(version);
|
||||||
|
out.writeByte(versionType.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,6 +267,9 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> {
|
||||||
String routing = null;
|
String routing = null;
|
||||||
String parent = null;
|
String parent = null;
|
||||||
List<String> fields = null;
|
List<String> fields = null;
|
||||||
|
long version = Versions.MATCH_ANY;
|
||||||
|
VersionType versionType = VersionType.INTERNAL;
|
||||||
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
|
@ -258,6 +287,10 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> {
|
||||||
} else if ("fields".equals(currentFieldName)) {
|
} else if ("fields".equals(currentFieldName)) {
|
||||||
fields = new ArrayList<String>();
|
fields = new ArrayList<String>();
|
||||||
fields.add(parser.text());
|
fields.add(parser.text());
|
||||||
|
} else if ("_version".equals(currentFieldName) || "version".equals(currentFieldName)) {
|
||||||
|
version = parser.longValue();
|
||||||
|
} else if ("_version_type".equals(currentFieldName) || "_versionType".equals(currentFieldName) || "version_type".equals(currentFieldName) || "versionType".equals(currentFieldName)) {
|
||||||
|
versionType = VersionType.fromString(parser.text());
|
||||||
}
|
}
|
||||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||||
if ("fields".equals(currentFieldName)) {
|
if ("fields".equals(currentFieldName)) {
|
||||||
|
@ -274,7 +307,7 @@ public class MultiGetRequest extends ActionRequest<MultiGetRequest> {
|
||||||
} else {
|
} else {
|
||||||
aFields = defaultFields;
|
aFields = defaultFields;
|
||||||
}
|
}
|
||||||
add(new Item(index, type, id).routing(routing).fields(aFields).parent(parent));
|
add(new Item(index, type, id).routing(routing).fields(aFields).parent(parent).version(version).versionType(versionType));
|
||||||
}
|
}
|
||||||
} else if ("ids".equals(currentFieldName)) {
|
} else if ("ids".equals(currentFieldName)) {
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
|
|
|
@ -20,10 +20,12 @@
|
||||||
package org.elasticsearch.action.get;
|
package org.elasticsearch.action.get;
|
||||||
|
|
||||||
import gnu.trove.list.array.TIntArrayList;
|
import gnu.trove.list.array.TIntArrayList;
|
||||||
|
import gnu.trove.list.array.TLongArrayList;
|
||||||
import org.elasticsearch.action.support.single.shard.SingleShardOperationRequest;
|
import org.elasticsearch.action.support.single.shard.SingleShardOperationRequest;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
import org.elasticsearch.index.VersionType;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -40,6 +42,8 @@ public class MultiGetShardRequest extends SingleShardOperationRequest<MultiGetSh
|
||||||
List<String> types;
|
List<String> types;
|
||||||
List<String> ids;
|
List<String> ids;
|
||||||
List<String[]> fields;
|
List<String[]> fields;
|
||||||
|
TLongArrayList versions;
|
||||||
|
List<VersionType> versionTypes;
|
||||||
|
|
||||||
MultiGetShardRequest() {
|
MultiGetShardRequest() {
|
||||||
|
|
||||||
|
@ -52,6 +56,8 @@ public class MultiGetShardRequest extends SingleShardOperationRequest<MultiGetSh
|
||||||
types = new ArrayList<String>();
|
types = new ArrayList<String>();
|
||||||
ids = new ArrayList<String>();
|
ids = new ArrayList<String>();
|
||||||
fields = new ArrayList<String[]>();
|
fields = new ArrayList<String[]>();
|
||||||
|
versions = new TLongArrayList();
|
||||||
|
versionTypes = new ArrayList<VersionType>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int shardId() {
|
public int shardId() {
|
||||||
|
@ -90,11 +96,13 @@ public class MultiGetShardRequest extends SingleShardOperationRequest<MultiGetSh
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(int location, @Nullable String type, String id, String[] fields) {
|
public void add(int location, @Nullable String type, String id, String[] fields, long version, VersionType versionType) {
|
||||||
this.locations.add(location);
|
this.locations.add(location);
|
||||||
this.types.add(type);
|
this.types.add(type);
|
||||||
this.ids.add(id);
|
this.ids.add(id);
|
||||||
this.fields.add(fields);
|
this.fields.add(fields);
|
||||||
|
this.versions.add(version);
|
||||||
|
this.versionTypes.add(versionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -105,6 +113,8 @@ public class MultiGetShardRequest extends SingleShardOperationRequest<MultiGetSh
|
||||||
types = new ArrayList<String>(size);
|
types = new ArrayList<String>(size);
|
||||||
ids = new ArrayList<String>(size);
|
ids = new ArrayList<String>(size);
|
||||||
fields = new ArrayList<String[]>(size);
|
fields = new ArrayList<String[]>(size);
|
||||||
|
versions = new TLongArrayList(size);
|
||||||
|
versionTypes = new ArrayList<VersionType>(size);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
locations.add(in.readVInt());
|
locations.add(in.readVInt());
|
||||||
if (in.readBoolean()) {
|
if (in.readBoolean()) {
|
||||||
|
@ -123,6 +133,8 @@ public class MultiGetShardRequest extends SingleShardOperationRequest<MultiGetSh
|
||||||
} else {
|
} else {
|
||||||
fields.add(null);
|
fields.add(null);
|
||||||
}
|
}
|
||||||
|
versions.add(in.readVLong());
|
||||||
|
versionTypes.add(VersionType.fromValue(in.readByte()));
|
||||||
}
|
}
|
||||||
|
|
||||||
preference = in.readOptionalString();
|
preference = in.readOptionalString();
|
||||||
|
@ -156,6 +168,8 @@ public class MultiGetShardRequest extends SingleShardOperationRequest<MultiGetSh
|
||||||
out.writeString(field);
|
out.writeString(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out.writeVLong(versions.get(i));
|
||||||
|
out.writeByte(versionTypes.get(i).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
out.writeOptionalString(preference);
|
out.writeOptionalString(preference);
|
||||||
|
|
|
@ -99,7 +99,8 @@ public class TransportGetAction extends TransportShardSingleOperationAction<GetR
|
||||||
indexShard.refresh(new Engine.Refresh(false));
|
indexShard.refresh(new Engine.Refresh(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
GetResult result = indexShard.getService().get(request.type(), request.id(), request.fields(), request.realtime());
|
GetResult result = indexShard.getService().get(request.type(), request.id(), request.fields(),
|
||||||
|
request.realtime(), request.version(), request.versionType());
|
||||||
return new GetResponse(result);
|
return new GetResponse(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class TransportMultiGetAction extends TransportAction<MultiGetRequest, Mu
|
||||||
|
|
||||||
shardRequests.put(shardId, shardRequest);
|
shardRequests.put(shardId, shardRequest);
|
||||||
}
|
}
|
||||||
shardRequest.add(i, item.type(), item.id(), item.fields());
|
shardRequest.add(i, item.type(), item.id(), item.fields(), item.version(), item.versionType());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shardRequests.size() == 0) {
|
if (shardRequests.size() == 0) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||||
import org.elasticsearch.cluster.routing.ShardIterator;
|
import org.elasticsearch.cluster.routing.ShardIterator;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.index.VersionType;
|
||||||
import org.elasticsearch.index.engine.Engine;
|
import org.elasticsearch.index.engine.Engine;
|
||||||
import org.elasticsearch.index.get.GetResult;
|
import org.elasticsearch.index.get.GetResult;
|
||||||
import org.elasticsearch.index.service.IndexService;
|
import org.elasticsearch.index.service.IndexService;
|
||||||
|
@ -111,9 +112,14 @@ public class TransportShardMultiGetAction extends TransportShardSingleOperationA
|
||||||
String type = request.types.get(i);
|
String type = request.types.get(i);
|
||||||
String id = request.ids.get(i);
|
String id = request.ids.get(i);
|
||||||
String[] fields = request.fields.get(i);
|
String[] fields = request.fields.get(i);
|
||||||
|
long version = request.versions.get(i);
|
||||||
|
VersionType versionType = request.versionTypes.get(i);
|
||||||
|
if (versionType == null) {
|
||||||
|
versionType = VersionType.INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
GetResult getResult = indexShard.getService().get(type, id, fields, request.realtime());
|
GetResult getResult = indexShard.getService().get(type, id, fields, request.realtime(), version, versionType);
|
||||||
response.add(request.locations.get(i), new GetResponse(getResult));
|
response.add(request.locations.get(i), new GetResponse(getResult));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.debug("[{}][{}] failed to execute multi_get for [{}]/[{}]", e, request.index(), shardId, type, id);
|
logger.debug("[{}][{}] failed to execute multi_get for [{}]/[{}]", e, request.index(), shardId, type, id);
|
||||||
|
|
|
@ -17,7 +17,6 @@ import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.index.VersionType;
|
import org.elasticsearch.index.VersionType;
|
||||||
import org.elasticsearch.index.engine.DocumentMissingException;
|
import org.elasticsearch.index.engine.DocumentMissingException;
|
||||||
import org.elasticsearch.index.engine.DocumentSourceMissingException;
|
import org.elasticsearch.index.engine.DocumentSourceMissingException;
|
||||||
import org.elasticsearch.index.engine.VersionConflictEngineException;
|
|
||||||
import org.elasticsearch.index.get.GetField;
|
import org.elasticsearch.index.get.GetField;
|
||||||
import org.elasticsearch.index.get.GetResult;
|
import org.elasticsearch.index.get.GetResult;
|
||||||
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
import org.elasticsearch.index.mapper.internal.ParentFieldMapper;
|
||||||
|
@ -65,7 +64,8 @@ public class UpdateHelper extends AbstractComponent {
|
||||||
public Result prepare(UpdateRequest request, IndexShard indexShard) {
|
public Result prepare(UpdateRequest request, IndexShard indexShard) {
|
||||||
long getDate = System.currentTimeMillis();
|
long getDate = System.currentTimeMillis();
|
||||||
final GetResult getResult = indexShard.getService().get(request.type(), request.id(),
|
final GetResult getResult = indexShard.getService().get(request.type(), request.id(),
|
||||||
new String[]{SourceFieldMapper.NAME, RoutingFieldMapper.NAME, ParentFieldMapper.NAME, TTLFieldMapper.NAME}, true);
|
new String[]{SourceFieldMapper.NAME, RoutingFieldMapper.NAME, ParentFieldMapper.NAME, TTLFieldMapper.NAME},
|
||||||
|
true, request.version(), request.versionType());
|
||||||
|
|
||||||
if (!getResult.isExists()) {
|
if (!getResult.isExists()) {
|
||||||
if (request.upsertRequest() == null && !request.docAsUpsert()) {
|
if (request.upsertRequest() == null && !request.docAsUpsert()) {
|
||||||
|
@ -86,11 +86,6 @@ public class UpdateHelper extends AbstractComponent {
|
||||||
return new Result(indexRequest, Operation.UPSERT, null, null);
|
return new Result(indexRequest, Operation.UPSERT, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.versionType().isVersionConflict(getResult.getVersion(), request.version())) {
|
|
||||||
throw new VersionConflictEngineException(new ShardId(request.index(), request.shardId()), request.type(), request.id(),
|
|
||||||
getResult.getVersion(), request.version());
|
|
||||||
}
|
|
||||||
|
|
||||||
long updateVersion = getResult.getVersion();
|
long updateVersion = getResult.getVersion();
|
||||||
if (request.versionType() == VersionType.EXTERNAL) {
|
if (request.versionType() == VersionType.EXTERNAL) {
|
||||||
updateVersion = request.version(); // remember, match_any is excluded by the conflict test
|
updateVersion = request.version(); // remember, match_any is excluded by the conflict test
|
||||||
|
|
|
@ -823,6 +823,8 @@ public interface Engine extends IndexShardComponent, CloseableComponent {
|
||||||
private final boolean realtime;
|
private final boolean realtime;
|
||||||
private final Term uid;
|
private final Term uid;
|
||||||
private boolean loadSource = true;
|
private boolean loadSource = true;
|
||||||
|
private long version;
|
||||||
|
private VersionType versionType;
|
||||||
|
|
||||||
public Get(boolean realtime, Term uid) {
|
public Get(boolean realtime, Term uid) {
|
||||||
this.realtime = realtime;
|
this.realtime = realtime;
|
||||||
|
@ -845,6 +847,24 @@ public interface Engine extends IndexShardComponent, CloseableComponent {
|
||||||
this.loadSource = loadSource;
|
this.loadSource = loadSource;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long version() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Get version(long version) {
|
||||||
|
this.version = version;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VersionType versionType() {
|
||||||
|
return versionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Get versionType(VersionType versionType) {
|
||||||
|
this.versionType = versionType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class GetResult {
|
static class GetResult {
|
||||||
|
|
|
@ -50,6 +50,7 @@ import org.elasticsearch.index.deletionpolicy.SnapshotDeletionPolicy;
|
||||||
import org.elasticsearch.index.deletionpolicy.SnapshotIndexCommit;
|
import org.elasticsearch.index.deletionpolicy.SnapshotIndexCommit;
|
||||||
import org.elasticsearch.index.engine.*;
|
import org.elasticsearch.index.engine.*;
|
||||||
import org.elasticsearch.index.indexing.ShardIndexingService;
|
import org.elasticsearch.index.indexing.ShardIndexingService;
|
||||||
|
import org.elasticsearch.index.mapper.Uid;
|
||||||
import org.elasticsearch.index.merge.policy.IndexUpgraderMergePolicy;
|
import org.elasticsearch.index.merge.policy.IndexUpgraderMergePolicy;
|
||||||
import org.elasticsearch.index.merge.policy.MergePolicyProvider;
|
import org.elasticsearch.index.merge.policy.MergePolicyProvider;
|
||||||
import org.elasticsearch.index.merge.scheduler.MergeSchedulerProvider;
|
import org.elasticsearch.index.merge.scheduler.MergeSchedulerProvider;
|
||||||
|
@ -315,6 +316,12 @@ public class RobinEngine extends AbstractIndexShardComponent implements Engine {
|
||||||
if (versionValue.delete()) {
|
if (versionValue.delete()) {
|
||||||
return GetResult.NOT_EXISTS;
|
return GetResult.NOT_EXISTS;
|
||||||
}
|
}
|
||||||
|
if (get.version() != Versions.MATCH_ANY) {
|
||||||
|
if (get.versionType().isVersionConflict(versionValue.version(), get.version())) {
|
||||||
|
Uid uid = Uid.createUid(get.uid().text());
|
||||||
|
throw new VersionConflictEngineException(shardId, uid.type(), uid.id(), versionValue.version(), get.version());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!get.loadSource()) {
|
if (!get.loadSource()) {
|
||||||
return new GetResult(true, versionValue.version(), null);
|
return new GetResult(true, versionValue.version(), null);
|
||||||
}
|
}
|
||||||
|
@ -332,19 +339,31 @@ public class RobinEngine extends AbstractIndexShardComponent implements Engine {
|
||||||
|
|
||||||
// no version, get the version from the index, we know that we refresh on flush
|
// no version, get the version from the index, we know that we refresh on flush
|
||||||
Searcher searcher = searcher();
|
Searcher searcher = searcher();
|
||||||
|
final Versions.DocIdAndVersion docIdAndVersion;
|
||||||
try {
|
try {
|
||||||
final Versions.DocIdAndVersion docIdAndVersion = Versions.loadDocIdAndVersion(searcher.reader(), get.uid());
|
docIdAndVersion = Versions.loadDocIdAndVersion(searcher.reader(), get.uid());
|
||||||
if (docIdAndVersion != null) {
|
|
||||||
return new GetResult(searcher, docIdAndVersion);
|
|
||||||
}
|
|
||||||
// don't release the searcher on this path, it is the responsability of the caller to call GetResult.release
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
searcher.release();
|
searcher.release();
|
||||||
//TODO: A better exception goes here
|
//TODO: A better exception goes here
|
||||||
throw new EngineException(shardId(), "Couldn't resolve version", e);
|
throw new EngineException(shardId(), "Couldn't resolve version", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get.version() != Versions.MATCH_ANY && docIdAndVersion != null) {
|
||||||
|
if (get.versionType().isVersionConflict(docIdAndVersion.version, get.version())) {
|
||||||
|
searcher.release();
|
||||||
|
Uid uid = Uid.createUid(get.uid().text());
|
||||||
|
throw new VersionConflictEngineException(shardId, uid.type(), uid.id(), docIdAndVersion.version, get.version());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (docIdAndVersion != null) {
|
||||||
|
// don't release the searcher on this path, it is the responsability of the caller to call GetResult.release
|
||||||
|
return new GetResult(searcher, docIdAndVersion);
|
||||||
|
} else {
|
||||||
searcher.release();
|
searcher.release();
|
||||||
return GetResult.NOT_EXISTS;
|
return GetResult.NOT_EXISTS;
|
||||||
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
rwl.readLock().unlock();
|
rwl.readLock().unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
import org.elasticsearch.common.xcontent.XContentType;
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
import org.elasticsearch.common.xcontent.support.XContentMapValues;
|
||||||
|
import org.elasticsearch.index.VersionType;
|
||||||
import org.elasticsearch.index.engine.Engine;
|
import org.elasticsearch.index.engine.Engine;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
import org.elasticsearch.index.fielddata.IndexFieldDataService;
|
||||||
import org.elasticsearch.index.fieldvisitor.CustomFieldsVisitor;
|
import org.elasticsearch.index.fieldvisitor.CustomFieldsVisitor;
|
||||||
|
@ -94,11 +95,11 @@ public class ShardGetService extends AbstractIndexShardComponent {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GetResult get(String type, String id, String[] gFields, boolean realtime) throws ElasticSearchException {
|
public GetResult get(String type, String id, String[] gFields, boolean realtime, long version, VersionType versionType) throws ElasticSearchException {
|
||||||
currentMetric.inc();
|
currentMetric.inc();
|
||||||
try {
|
try {
|
||||||
long now = System.nanoTime();
|
long now = System.nanoTime();
|
||||||
GetResult getResult = innerGet(type, id, gFields, realtime);
|
GetResult getResult = innerGet(type, id, gFields, realtime, version, versionType);
|
||||||
if (getResult.isExists()) {
|
if (getResult.isExists()) {
|
||||||
existsMetric.inc(System.nanoTime() - now);
|
existsMetric.inc(System.nanoTime() - now);
|
||||||
} else {
|
} else {
|
||||||
|
@ -143,12 +144,13 @@ public class ShardGetService extends AbstractIndexShardComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GetResult innerGet(String type, String id, String[] gFields, boolean realtime) throws ElasticSearchException {
|
public GetResult innerGet(String type, String id, String[] gFields, boolean realtime, long version, VersionType versionType) throws ElasticSearchException {
|
||||||
boolean loadSource = gFields == null || gFields.length > 0;
|
boolean loadSource = gFields == null || gFields.length > 0;
|
||||||
Engine.GetResult get = null;
|
Engine.GetResult get = null;
|
||||||
if (type == null || type.equals("_all")) {
|
if (type == null || type.equals("_all")) {
|
||||||
for (String typeX : mapperService.types()) {
|
for (String typeX : mapperService.types()) {
|
||||||
get = indexShard.get(new Engine.Get(realtime, new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(typeX, id))).loadSource(loadSource));
|
get = indexShard.get(new Engine.Get(realtime, new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(typeX, id)))
|
||||||
|
.loadSource(loadSource).version(version).versionType(versionType));
|
||||||
if (get.exists()) {
|
if (get.exists()) {
|
||||||
type = typeX;
|
type = typeX;
|
||||||
break;
|
break;
|
||||||
|
@ -164,7 +166,8 @@ public class ShardGetService extends AbstractIndexShardComponent {
|
||||||
return new GetResult(shardId.index().name(), type, id, -1, false, null, null);
|
return new GetResult(shardId.index().name(), type, id, -1, false, null, null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
get = indexShard.get(new Engine.Get(realtime, new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(type, id))).loadSource(loadSource));
|
get = indexShard.get(new Engine.Get(realtime, new Term(UidFieldMapper.NAME, Uid.createUidAsBytes(type, id)))
|
||||||
|
.loadSource(loadSource).version(version).versionType(versionType));
|
||||||
if (!get.exists()) {
|
if (!get.exists()) {
|
||||||
get.release();
|
get.release();
|
||||||
return new GetResult(shardId.index().name(), type, id, -1, false, null, null);
|
return new GetResult(shardId.index().name(), type, id, -1, false, null, null);
|
||||||
|
|
|
@ -27,7 +27,9 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.index.VersionType;
|
||||||
import org.elasticsearch.rest.*;
|
import org.elasticsearch.rest.*;
|
||||||
|
import org.elasticsearch.rest.action.support.RestActions;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -66,6 +68,9 @@ public class RestGetAction extends BaseRestHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getRequest.version(RestActions.parseVersion(request));
|
||||||
|
getRequest.versionType(VersionType.fromString(request.param("version_type"), getRequest.versionType()));
|
||||||
|
|
||||||
|
|
||||||
client.get(getRequest, new ActionListener<GetResponse>() {
|
client.get(getRequest, new ActionListener<GetResponse>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.elasticsearch.common.bytes.BytesArray;
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
|
import org.elasticsearch.index.engine.VersionConflictEngineException;
|
||||||
import org.elasticsearch.test.integration.AbstractSharedClusterTest;
|
import org.elasticsearch.test.integration.AbstractSharedClusterTest;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -496,4 +497,207 @@ public class GetActionTests extends AbstractSharedClusterTest {
|
||||||
assertThat(responseBeforeFlush.getSourceAsString(), is(responseAfterFlush.getSourceAsString()));
|
assertThat(responseBeforeFlush.getSourceAsString(), is(responseAfterFlush.getSourceAsString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetWithVersion() {
|
||||||
|
client().admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("index.refresh_interval", -1)).execute().actionGet();
|
||||||
|
ClusterHealthResponse clusterHealth = client().admin().cluster().health(clusterHealthRequest().waitForGreenStatus()).actionGet();
|
||||||
|
assertThat(clusterHealth.isTimedOut(), equalTo(false));
|
||||||
|
assertThat(clusterHealth.getStatus(), equalTo(ClusterHealthStatus.GREEN));
|
||||||
|
|
||||||
|
GetResponse response = client().prepareGet("test", "type1", "1").execute().actionGet();
|
||||||
|
assertThat(response.isExists(), equalTo(false));
|
||||||
|
|
||||||
|
logger.info("--> index doc 1");
|
||||||
|
client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2").execute().actionGet();
|
||||||
|
|
||||||
|
// From translog:
|
||||||
|
|
||||||
|
// version 0 means ignore version, which is the default
|
||||||
|
response = client().prepareGet("test", "type1", "1").setVersion(0).execute().actionGet();
|
||||||
|
assertThat(response.isExists(), equalTo(true));
|
||||||
|
assertThat(response.getId(), equalTo("1"));
|
||||||
|
assertThat(response.getVersion(), equalTo(1l));
|
||||||
|
|
||||||
|
response = client().prepareGet("test", "type1", "1").setVersion(1).execute().actionGet();
|
||||||
|
assertThat(response.isExists(), equalTo(true));
|
||||||
|
assertThat(response.getId(), equalTo("1"));
|
||||||
|
assertThat(response.getVersion(), equalTo(1l));
|
||||||
|
|
||||||
|
try {
|
||||||
|
client().prepareGet("test", "type1", "1").setVersion(2).execute().actionGet();
|
||||||
|
assert false;
|
||||||
|
} catch (VersionConflictEngineException e) {}
|
||||||
|
|
||||||
|
// From Lucene index:
|
||||||
|
client().admin().indices().prepareRefresh("test").execute().actionGet();
|
||||||
|
|
||||||
|
// version 0 means ignore version, which is the default
|
||||||
|
response = client().prepareGet("test", "type1", "1").setVersion(0).setRealtime(false).execute().actionGet();
|
||||||
|
assertThat(response.isExists(), equalTo(true));
|
||||||
|
assertThat(response.getId(), equalTo("1"));
|
||||||
|
assertThat(response.getVersion(), equalTo(1l));
|
||||||
|
|
||||||
|
response = client().prepareGet("test", "type1", "1").setVersion(1).setRealtime(false).execute().actionGet();
|
||||||
|
assertThat(response.isExists(), equalTo(true));
|
||||||
|
assertThat(response.getId(), equalTo("1"));
|
||||||
|
assertThat(response.getVersion(), equalTo(1l));
|
||||||
|
|
||||||
|
try {
|
||||||
|
client().prepareGet("test", "type1", "1").setVersion(2).setRealtime(false).execute().actionGet();
|
||||||
|
assert false;
|
||||||
|
} catch (VersionConflictEngineException e) {}
|
||||||
|
|
||||||
|
logger.info("--> index doc 1 again, so increasing the version");
|
||||||
|
client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2").execute().actionGet();
|
||||||
|
|
||||||
|
// From translog:
|
||||||
|
|
||||||
|
// version 0 means ignore version, which is the default
|
||||||
|
response = client().prepareGet("test", "type1", "1").setVersion(0).execute().actionGet();
|
||||||
|
assertThat(response.isExists(), equalTo(true));
|
||||||
|
assertThat(response.getId(), equalTo("1"));
|
||||||
|
assertThat(response.getVersion(), equalTo(2l));
|
||||||
|
|
||||||
|
try {
|
||||||
|
client().prepareGet("test", "type1", "1").setVersion(1).execute().actionGet();
|
||||||
|
assert false;
|
||||||
|
} catch (VersionConflictEngineException e) {}
|
||||||
|
|
||||||
|
response = client().prepareGet("test", "type1", "1").setVersion(2).execute().actionGet();
|
||||||
|
assertThat(response.isExists(), equalTo(true));
|
||||||
|
assertThat(response.getId(), equalTo("1"));
|
||||||
|
assertThat(response.getVersion(), equalTo(2l));
|
||||||
|
|
||||||
|
// From Lucene index:
|
||||||
|
client().admin().indices().prepareRefresh("test").execute().actionGet();
|
||||||
|
|
||||||
|
// version 0 means ignore version, which is the default
|
||||||
|
response = client().prepareGet("test", "type1", "1").setVersion(0).setRealtime(false).execute().actionGet();
|
||||||
|
assertThat(response.isExists(), equalTo(true));
|
||||||
|
assertThat(response.getId(), equalTo("1"));
|
||||||
|
assertThat(response.getVersion(), equalTo(2l));
|
||||||
|
|
||||||
|
try {
|
||||||
|
client().prepareGet("test", "type1", "1").setVersion(1).setRealtime(false).execute().actionGet();
|
||||||
|
assert false;
|
||||||
|
} catch (VersionConflictEngineException e) {}
|
||||||
|
|
||||||
|
response = client().prepareGet("test", "type1", "1").setVersion(2).setRealtime(false).execute().actionGet();
|
||||||
|
assertThat(response.isExists(), equalTo(true));
|
||||||
|
assertThat(response.getId(), equalTo("1"));
|
||||||
|
assertThat(response.getVersion(), equalTo(2l));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiGetWithVersion() throws Exception {
|
||||||
|
try {
|
||||||
|
client().admin().indices().prepareDelete("test").execute().actionGet();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// fine
|
||||||
|
}
|
||||||
|
client().admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("index.refresh_interval", -1)).execute().actionGet();
|
||||||
|
|
||||||
|
ClusterHealthResponse clusterHealth = client().admin().cluster().health(clusterHealthRequest().waitForGreenStatus()).actionGet();
|
||||||
|
assertThat(clusterHealth.isTimedOut(), equalTo(false));
|
||||||
|
assertThat(clusterHealth.getStatus(), equalTo(ClusterHealthStatus.GREEN));
|
||||||
|
|
||||||
|
MultiGetResponse response = client().prepareMultiGet().add("test", "type1", "1").execute().actionGet();
|
||||||
|
assertThat(response.getResponses().length, equalTo(1));
|
||||||
|
assertThat(response.getResponses()[0].getResponse().isExists(), equalTo(false));
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
client().prepareIndex("test", "type1", Integer.toString(i)).setSource("field", "value" + i).execute().actionGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version from translog
|
||||||
|
response = client().prepareMultiGet()
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "1").version(0))
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "1").version(1))
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "1").version(2))
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(response.getResponses().length, equalTo(3));
|
||||||
|
// [0] version doesn't matter, which is the default
|
||||||
|
assertThat(response.getResponses()[0].getFailure(), nullValue());
|
||||||
|
assertThat(response.getResponses()[0].getId(), equalTo("1"));
|
||||||
|
assertThat(response.getResponses()[0].getResponse().isExists(), equalTo(true));
|
||||||
|
assertThat(response.getResponses()[0].getResponse().getSourceAsMap().get("field").toString(), equalTo("value1"));
|
||||||
|
assertThat(response.getResponses()[1].getId(), equalTo("1"));
|
||||||
|
assertThat(response.getResponses()[1].getFailure(), nullValue());
|
||||||
|
assertThat(response.getResponses()[1].getResponse().isExists(), equalTo(true));
|
||||||
|
assertThat(response.getResponses()[1].getResponse().getSourceAsMap().get("field").toString(), equalTo("value1"));
|
||||||
|
assertThat(response.getResponses()[2].getFailure(), notNullValue());
|
||||||
|
assertThat(response.getResponses()[2].getFailure().getId(), equalTo("1"));
|
||||||
|
assertThat(response.getResponses()[2].getFailure().getMessage(), startsWith("VersionConflictEngineException"));
|
||||||
|
|
||||||
|
//Version from Lucene index
|
||||||
|
client().admin().indices().prepareRefresh("test").execute().actionGet();
|
||||||
|
response = client().prepareMultiGet()
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "1").version(0))
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "1").version(1))
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "1").version(2))
|
||||||
|
.setRealtime(false)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(response.getResponses().length, equalTo(3));
|
||||||
|
// [0] version doesn't matter, which is the default
|
||||||
|
assertThat(response.getResponses()[0].getFailure(), nullValue());
|
||||||
|
assertThat(response.getResponses()[0].getId(), equalTo("1"));
|
||||||
|
assertThat(response.getResponses()[0].getResponse().isExists(), equalTo(true));
|
||||||
|
assertThat(response.getResponses()[0].getResponse().getSourceAsMap().get("field").toString(), equalTo("value1"));
|
||||||
|
assertThat(response.getResponses()[1].getId(), equalTo("1"));
|
||||||
|
assertThat(response.getResponses()[1].getFailure(), nullValue());
|
||||||
|
assertThat(response.getResponses()[1].getResponse().isExists(), equalTo(true));
|
||||||
|
assertThat(response.getResponses()[1].getResponse().getSourceAsMap().get("field").toString(), equalTo("value1"));
|
||||||
|
assertThat(response.getResponses()[2].getFailure(), notNullValue());
|
||||||
|
assertThat(response.getResponses()[2].getFailure().getId(), equalTo("1"));
|
||||||
|
assertThat(response.getResponses()[2].getFailure().getMessage(), startsWith("VersionConflictEngineException"));
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
client().prepareIndex("test", "type1", Integer.toString(i)).setSource("field", "value" + i).execute().actionGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version from translog
|
||||||
|
response = client().prepareMultiGet()
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "2").version(0))
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "2").version(1))
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "2").version(2))
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(response.getResponses().length, equalTo(3));
|
||||||
|
// [0] version doesn't matter, which is the default
|
||||||
|
assertThat(response.getResponses()[0].getFailure(), nullValue());
|
||||||
|
assertThat(response.getResponses()[0].getId(), equalTo("2"));
|
||||||
|
assertThat(response.getResponses()[0].getResponse().isExists(), equalTo(true));
|
||||||
|
assertThat(response.getResponses()[0].getResponse().getSourceAsMap().get("field").toString(), equalTo("value2"));
|
||||||
|
assertThat(response.getResponses()[1].getFailure(), notNullValue());
|
||||||
|
assertThat(response.getResponses()[1].getFailure().getId(), equalTo("2"));
|
||||||
|
assertThat(response.getResponses()[1].getFailure().getMessage(), startsWith("VersionConflictEngineException"));
|
||||||
|
assertThat(response.getResponses()[2].getId(), equalTo("2"));
|
||||||
|
assertThat(response.getResponses()[2].getFailure(), nullValue());
|
||||||
|
assertThat(response.getResponses()[2].getResponse().isExists(), equalTo(true));
|
||||||
|
assertThat(response.getResponses()[2].getResponse().getSourceAsMap().get("field").toString(), equalTo("value2"));
|
||||||
|
|
||||||
|
|
||||||
|
//Version from Lucene index
|
||||||
|
client().admin().indices().prepareRefresh("test").execute().actionGet();
|
||||||
|
response = client().prepareMultiGet()
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "2").version(0))
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "2").version(1))
|
||||||
|
.add(new MultiGetRequest.Item("test", "type1", "2").version(2))
|
||||||
|
.setRealtime(false)
|
||||||
|
.execute().actionGet();
|
||||||
|
assertThat(response.getResponses().length, equalTo(3));
|
||||||
|
// [0] version doesn't matter, which is the default
|
||||||
|
assertThat(response.getResponses()[0].getFailure(), nullValue());
|
||||||
|
assertThat(response.getResponses()[0].getId(), equalTo("2"));
|
||||||
|
assertThat(response.getResponses()[0].getResponse().isExists(), equalTo(true));
|
||||||
|
assertThat(response.getResponses()[0].getResponse().getSourceAsMap().get("field").toString(), equalTo("value2"));
|
||||||
|
assertThat(response.getResponses()[1].getFailure(), notNullValue());
|
||||||
|
assertThat(response.getResponses()[1].getFailure().getId(), equalTo("2"));
|
||||||
|
assertThat(response.getResponses()[1].getFailure().getMessage(), startsWith("VersionConflictEngineException"));
|
||||||
|
assertThat(response.getResponses()[2].getId(), equalTo("2"));
|
||||||
|
assertThat(response.getResponses()[2].getFailure(), nullValue());
|
||||||
|
assertThat(response.getResponses()[2].getResponse().isExists(), equalTo(true));
|
||||||
|
assertThat(response.getResponses()[2].getResponse().getSourceAsMap().get("field").toString(), equalTo("value2"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue