Skip to content

Commit 6243f4f

Browse files
committed
Get API: Allow to specify which fields to load, close #65.
1 parent 4c13a9d commit 6243f4f

File tree

5 files changed

+392
-25
lines changed

5 files changed

+392
-25
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*
2+
* Licensed to Elastic Search and Shay Banon under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. Elastic Search licenses this
6+
* file to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.action.get;
21+
22+
import org.elasticsearch.util.io.Streamable;
23+
24+
import java.io.DataInput;
25+
import java.io.DataOutput;
26+
import java.io.IOException;
27+
import java.util.ArrayList;
28+
import java.util.Iterator;
29+
import java.util.List;
30+
31+
/**
32+
* @author kimchy (shay.banon)
33+
*/
34+
public class GetField implements Streamable, Iterable<Object> {
35+
36+
private String name;
37+
38+
private List<Object> values;
39+
40+
private GetField() {
41+
42+
}
43+
44+
public GetField(String name, List<Object> values) {
45+
this.name = name;
46+
this.values = values;
47+
}
48+
49+
public String name() {
50+
return name;
51+
}
52+
53+
public List<Object> values() {
54+
return values;
55+
}
56+
57+
@Override public Iterator<Object> iterator() {
58+
return values.iterator();
59+
}
60+
61+
public static GetField readGetField(DataInput in) throws IOException, ClassNotFoundException {
62+
GetField result = new GetField();
63+
result.readFrom(in);
64+
return result;
65+
}
66+
67+
@Override public void readFrom(DataInput in) throws IOException, ClassNotFoundException {
68+
name = in.readUTF();
69+
int size = in.readInt();
70+
values = new ArrayList<Object>(size);
71+
for (int i = 0; i < size; i++) {
72+
Object value;
73+
byte type = in.readByte();
74+
if (type == 0) {
75+
value = in.readUTF();
76+
} else if (type == 1) {
77+
value = in.readInt();
78+
} else if (type == 2) {
79+
value = in.readLong();
80+
} else if (type == 3) {
81+
value = in.readFloat();
82+
} else if (type == 4) {
83+
value = in.readDouble();
84+
} else if (type == 5) {
85+
value = in.readBoolean();
86+
} else if (type == 6) {
87+
int bytesSize = in.readInt();
88+
value = new byte[bytesSize];
89+
in.readFully(((byte[]) value));
90+
} else {
91+
throw new IOException("Can't read unknown type [" + type + "]");
92+
}
93+
values.add(value);
94+
}
95+
}
96+
97+
@Override public void writeTo(DataOutput out) throws IOException {
98+
out.writeUTF(name);
99+
out.writeInt(values.size());
100+
for (Object obj : values) {
101+
Class type = obj.getClass();
102+
if (type == String.class) {
103+
out.write(0);
104+
out.writeUTF((String) obj);
105+
} else if (type == Integer.class) {
106+
out.write(1);
107+
out.writeInt((Integer) obj);
108+
} else if (type == Long.class) {
109+
out.write(2);
110+
out.writeLong((Long) obj);
111+
} else if (type == Float.class) {
112+
out.write(3);
113+
out.writeFloat((Float) obj);
114+
} else if (type == Double.class) {
115+
out.write(4);
116+
out.writeDouble((Double) obj);
117+
} else if (type == Boolean.class) {
118+
out.write(5);
119+
out.writeBoolean((Boolean) obj);
120+
} else if (type == byte[].class) {
121+
out.write(6);
122+
out.writeInt(((byte[]) obj).length);
123+
out.write(((byte[]) obj));
124+
} else {
125+
throw new IOException("Can't write type [" + type + "]");
126+
}
127+
}
128+
}
129+
}

modules/elasticsearch/src/main/java/org/elasticsearch/action/get/GetRequest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
*/
4141
public class GetRequest extends SingleOperationRequest {
4242

43+
private String[] fields;
44+
4345
GetRequest() {
4446
}
4547

@@ -78,6 +80,23 @@ public GetRequest(String index, String type, String id) {
7880
return this;
7981
}
8082

83+
/**
84+
* Explicitly specify the fields that will be returned. By default, the <tt>_source</tt>
85+
* field will be returned.
86+
*/
87+
public GetRequest fields(String... fields) {
88+
this.fields = fields;
89+
return this;
90+
}
91+
92+
/**
93+
* Explicitly specify the fields that will be returned. By default, the <tt>_source</tt>
94+
* field will be returned.
95+
*/
96+
public String[] fields() {
97+
return this.fields;
98+
}
99+
81100
/**
82101
* Should the listener be called on a separate thread if needed.
83102
*/
@@ -96,10 +115,25 @@ public GetRequest(String index, String type, String id) {
96115

97116
@Override public void readFrom(DataInput in) throws IOException, ClassNotFoundException {
98117
super.readFrom(in);
118+
int size = in.readInt();
119+
if (size >= 0) {
120+
fields = new String[size];
121+
for (int i = 0; i < size; i++) {
122+
fields[i] = in.readUTF();
123+
}
124+
}
99125
}
100126

101127
@Override public void writeTo(DataOutput out) throws IOException {
102128
super.writeTo(out);
129+
if (fields == null) {
130+
out.writeInt(-1);
131+
} else {
132+
out.writeInt(fields.length);
133+
for (String field : fields) {
134+
out.writeUTF(field);
135+
}
136+
}
103137
}
104138

105139
@Override public String toString() {

modules/elasticsearch/src/main/java/org/elasticsearch/action/get/GetResponse.java

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@
2727
import java.io.DataInput;
2828
import java.io.DataOutput;
2929
import java.io.IOException;
30+
import java.util.Iterator;
3031
import java.util.Map;
3132

33+
import static com.google.common.collect.Iterators.*;
34+
import static com.google.common.collect.Maps.*;
35+
import static org.elasticsearch.action.get.GetField.*;
3236
import static org.elasticsearch.util.json.Jackson.*;
3337

3438
/**
@@ -38,31 +42,37 @@
3842
* @see GetRequest
3943
* @see org.elasticsearch.client.Client#get(GetRequest)
4044
*/
41-
public class GetResponse implements ActionResponse, Streamable {
45+
public class GetResponse implements ActionResponse, Streamable, Iterable<GetField> {
4246

4347
private String index;
4448

4549
private String type;
4650

4751
private String id;
4852

53+
private boolean exists;
54+
55+
private Map<String, GetField> fields;
56+
4957
private byte[] source;
5058

5159
GetResponse() {
5260
}
5361

54-
GetResponse(String index, String type, String id, byte[] source) {
62+
GetResponse(String index, String type, String id, boolean exists, byte[] source, Map<String, GetField> fields) {
5563
this.index = index;
5664
this.type = type;
5765
this.id = id;
66+
this.exists = exists;
5867
this.source = source;
68+
this.fields = fields;
5969
}
6070

6171
/**
6272
* Does the document exists.
6373
*/
6474
public boolean exists() {
65-
return source != null && source.length > 0;
75+
return exists;
6676
}
6777

6878
/**
@@ -103,8 +113,9 @@ public String sourceAsString() {
103113
/**
104114
* The source of the document (As a map).
105115
*/
116+
@SuppressWarnings({"unchecked"})
106117
public Map<String, Object> sourceAsMap() throws ElasticSearchParseException {
107-
if (!exists()) {
118+
if (source == null) {
108119
return null;
109120
}
110121
try {
@@ -114,26 +125,63 @@ public Map<String, Object> sourceAsMap() throws ElasticSearchParseException {
114125
}
115126
}
116127

128+
public Map<String, GetField> fields() {
129+
return this.fields;
130+
}
131+
132+
public GetField field(String name) {
133+
return fields.get(name);
134+
}
135+
136+
@Override public Iterator<GetField> iterator() {
137+
if (fields == null) {
138+
return emptyIterator();
139+
}
140+
return fields.values().iterator();
141+
}
142+
117143
@Override public void readFrom(DataInput in) throws IOException, ClassNotFoundException {
118144
index = in.readUTF();
119145
type = in.readUTF();
120146
id = in.readUTF();
121-
int size = in.readInt();
122-
if (size > 0) {
123-
source = new byte[size];
124-
in.readFully(source);
147+
exists = in.readBoolean();
148+
if (exists) {
149+
int size = in.readInt();
150+
if (size > 0) {
151+
source = new byte[size];
152+
in.readFully(source);
153+
}
154+
size = in.readInt();
155+
if (size > 0) {
156+
fields = newHashMapWithExpectedSize(size);
157+
for (int i = 0; i < size; i++) {
158+
GetField field = readGetField(in);
159+
fields.put(field.name(), field);
160+
}
161+
}
125162
}
126163
}
127164

128165
@Override public void writeTo(DataOutput out) throws IOException {
129166
out.writeUTF(index);
130167
out.writeUTF(type);
131168
out.writeUTF(id);
132-
if (source == null) {
133-
out.writeInt(0);
134-
} else {
135-
out.writeInt(source.length);
136-
out.write(source);
169+
out.writeBoolean(exists);
170+
if (exists) {
171+
if (source == null) {
172+
out.writeInt(0);
173+
} else {
174+
out.writeInt(source.length);
175+
out.write(source);
176+
}
177+
if (fields == null) {
178+
out.writeInt(0);
179+
} else {
180+
out.writeInt(fields.size());
181+
for (GetField field : fields.values()) {
182+
field.writeTo(out);
183+
}
184+
}
137185
}
138186
}
139187
}

0 commit comments

Comments
 (0)