package crate.elasticsearch.searchinto.mapping;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.index.mapper.internal.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import java.util.Map;
public class FieldReader {
private final String name;
private HitReader reader;
private SearchHit hit;
private final static ImmutableMap<String, HitReader> readers;
static {
readers = MapBuilder.<String, HitReader>newMapBuilder().put(
SourceFieldMapper.NAME, new HitReader<Map<String, Object>>() {
@Override
public Map<String, Object> read(SearchHit hit) {
return hit.getSource();
}
}).put(IndexFieldMapper.NAME, new HitReader<String>() {
@Override
public String read(SearchHit hit) {
return hit.index();
}
}).put(TypeFieldMapper.NAME, new HitReader<String>() {
@Override
public String read(SearchHit hit) {
return hit.type();
}
}).put(IdFieldMapper.NAME, new HitReader<String>() {
@Override
public String read(SearchHit hit) {
return hit.id();
}
}).put(TimestampFieldMapper.NAME, new HitReader<Long>() {
@Override
public Long read(SearchHit hit) {
SearchHitField field = hit.getFields().get(
TimestampFieldMapper.NAME);
if (field != null && !field.values().isEmpty()) {
return field.value();
}
return null;
}
}).put(TTLFieldMapper.NAME, new HitReader<Long>() {
@Override
public Long read(SearchHit hit) {
SearchHitField field = hit.getFields().get(
TTLFieldMapper.NAME);
if (field != null && !field.values().isEmpty()) {
return field.value();
}
return null;
}
}).put("_version", new HitReader<Long>() {
@Override
public Long read(SearchHit hit) {
return hit.getVersion();
}
}).immutableMap();
}
static abstract class HitReader<T> {
public abstract T read(SearchHit hit);
}
static class HitFieldReader extends HitReader {
private final String name;
HitFieldReader(String name) {
this.name = name;
}
@Override
public Object read(SearchHit hit) {
SearchHitField field = hit.getFields().get(name);
if (field != null && !field.values().isEmpty()) {
if (field.values().size() == 1) {
return field.values().get(0);
} else {
return field.values();
}
}
return null;
}
}
public FieldReader(String name) {
this.name = name;
initReader();
}
private void initReader() {
if (name.startsWith("_")) {
reader = readers.get(name);
}
if (reader == null) {
reader = new HitFieldReader(name);
}
}
public void setHit(SearchHit hit) {
this.hit = hit;
}
public Object getValue() {
return reader.read(hit);
}
}