Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow realtime get to read from translog #48843

Merged
10 changes: 5 additions & 5 deletions docs/reference/docs/get.asciidoc
Expand Up @@ -35,11 +35,11 @@ that it exists.
===== Realtime

By default, the get API is realtime, and is not affected by the refresh
rate of the index (when data will become visible for search). If a document
has been updated but is not yet refreshed, the get API will issue a refresh
call in-place to make the document visible. This will also make other documents
changed since the last refresh visible. In order to disable realtime GET,
one can set the `realtime` parameter to `false`.
rate of the index (when data will become visible for search). In case where
stored fields are requested (see `stored_fields` parameter) and the document
has been updated but is not yet refreshed, the get API will have to parse
and analyze the source to extract the stored fields. In order to disable
realtime GET, the `realtime` parameter can be set to `false`.

[float]
[[get-source-filtering]]
Expand Down
Expand Up @@ -35,6 +35,7 @@
import org.apache.lucene.index.Terms;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.index.mapper.IdFieldMapper;
import org.elasticsearch.index.mapper.RoutingFieldMapper;
import org.elasticsearch.index.mapper.SourceFieldMapper;
Expand All @@ -44,11 +45,12 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Set;

/**
* Internal class that mocks a single doc read from the transaction log as a leaf reader.
*/
final class TranslogLeafReader extends LeafReader {
public final class TranslogLeafReader extends LeafReader {

private final Translog.Index operation;
private static final FieldInfo FAKE_SOURCE_FIELD
Expand All @@ -60,6 +62,7 @@ final class TranslogLeafReader extends LeafReader {
private static final FieldInfo FAKE_ID_FIELD
= new FieldInfo(IdFieldMapper.NAME, 3, false, false, false, IndexOptions.NONE, DocValuesType.NONE, -1, Collections.emptyMap(),
0, 0, 0, false);
public static Set<String> ALL_FIELD_NAMES = Sets.newHashSet(FAKE_SOURCE_FIELD.name, FAKE_ROUTING_FIELD.name, FAKE_ID_FIELD.name);
ywelsch marked this conversation as resolved.
Show resolved Hide resolved

TranslogLeafReader(Translog.Index operation) {
this.operation = operation;
Expand Down Expand Up @@ -161,7 +164,7 @@ public void document(int docID, StoredFieldVisitor visitor) throws IOException {
BytesRef bytesRef = Uid.encodeId(operation.id());
final byte[] id = new byte[bytesRef.length];
System.arraycopy(bytesRef.bytes, bytesRef.offset, id, 0, bytesRef.length);
visitor.stringField(FAKE_ID_FIELD, id);
visitor.binaryField(FAKE_ID_FIELD, id);
}
}

Expand Down
Expand Up @@ -20,7 +20,6 @@

import org.apache.lucene.index.FieldInfo;

import java.io.IOException;
import java.util.Set;

/**
Expand All @@ -39,7 +38,7 @@ public CustomFieldsVisitor(Set<String> fields, boolean loadSource) {
}

@Override
public Status needsField(FieldInfo fieldInfo) throws IOException {
public Status needsField(FieldInfo fieldInfo) {
if (super.needsField(fieldInfo) == Status.YES) {
return Status.YES;
}
Expand Down
Expand Up @@ -32,7 +32,6 @@
import org.elasticsearch.index.mapper.SourceFieldMapper;
import org.elasticsearch.index.mapper.Uid;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -72,7 +71,7 @@ public FieldsVisitor(boolean loadSource, String sourceFieldName) {
}

@Override
public Status needsField(FieldInfo fieldInfo) throws IOException {
public Status needsField(FieldInfo fieldInfo) {
if (requiredFields.remove(fieldInfo.name)) {
return Status.YES;
}
Expand Down Expand Up @@ -108,42 +107,54 @@ public void postProcess(MapperService mapperService) {
}

@Override
public void binaryField(FieldInfo fieldInfo, byte[] value) throws IOException {
public void binaryField(FieldInfo fieldInfo, byte[] value) {
binaryField(fieldInfo, new BytesRef(value));
}

public void binaryField(FieldInfo fieldInfo, BytesRef value) {
if (sourceFieldName.equals(fieldInfo.name)) {
source = new BytesArray(value);
} else if (IdFieldMapper.NAME.equals(fieldInfo.name)) {
id = Uid.decodeId(value);
id = Uid.decodeId(value.bytes, value.offset, value.length);
} else {
addValue(fieldInfo.name, new BytesRef(value));
addValue(fieldInfo.name, value);
}
}

@Override
public void stringField(FieldInfo fieldInfo, byte[] bytes) throws IOException {
public void stringField(FieldInfo fieldInfo, byte[] bytes) {
assert IdFieldMapper.NAME.equals(fieldInfo.name) == false : "_id field must go through binaryField";
assert sourceFieldName.equals(fieldInfo.name) == false : "source field must go through binaryField";
final String value = new String(bytes, StandardCharsets.UTF_8);
addValue(fieldInfo.name, value);
}

@Override
public void intField(FieldInfo fieldInfo, int value) throws IOException {
public void intField(FieldInfo fieldInfo, int value) {
addValue(fieldInfo.name, value);
}

@Override
public void longField(FieldInfo fieldInfo, long value) throws IOException {
public void longField(FieldInfo fieldInfo, long value) {
addValue(fieldInfo.name, value);
}

@Override
public void floatField(FieldInfo fieldInfo, float value) throws IOException {
public void floatField(FieldInfo fieldInfo, float value) {
addValue(fieldInfo.name, value);
}

@Override
public void doubleField(FieldInfo fieldInfo, double value) throws IOException {
public void doubleField(FieldInfo fieldInfo, double value) {
addValue(fieldInfo.name, value);
}

public void objectField(FieldInfo fieldInfo, Object object) {
assert IdFieldMapper.NAME.equals(fieldInfo.name) == false : "_id field must go through binaryField";
assert sourceFieldName.equals(fieldInfo.name) == false : "source field must go through binaryField";
addValue(fieldInfo.name, object);
}

public BytesReference source() {
return source;
}
Expand Down