Java API: Expose source as Map (in GetResponse, SearchHit), allow to index a Map, closes #58.
This commit is contained in:
parent
4b04db9030
commit
86c3a406c6
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Licensed to Elastic Search and Shay Banon under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. Elastic Search licenses this
|
||||
* file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch;
|
||||
|
||||
/**
|
||||
* A generic exception indicating failure to generate.
|
||||
*
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class ElasticSearchGenerationException extends ElasticSearchException {
|
||||
|
||||
public ElasticSearchGenerationException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public ElasticSearchGenerationException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.action.get;
|
||||
|
||||
import org.elasticsearch.ElasticSearchParseException;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.util.Unicode;
|
||||
import org.elasticsearch.util.io.Streamable;
|
||||
|
@ -26,6 +27,9 @@ import org.elasticsearch.util.io.Streamable;
|
|||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.util.json.Jackson.*;
|
||||
|
||||
/**
|
||||
* The response of a get action.
|
||||
|
@ -96,6 +100,20 @@ public class GetResponse implements ActionResponse, Streamable {
|
|||
return Unicode.fromBytes(source);
|
||||
}
|
||||
|
||||
/**
|
||||
* The source of the document (As a map).
|
||||
*/
|
||||
public Map<String, Object> sourceAsMap() throws ElasticSearchParseException {
|
||||
if (!exists()) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return defaultObjectMapper().readValue(source, 0, source.length, Map.class);
|
||||
} catch (Exception e) {
|
||||
throw new ElasticSearchParseException("Failed to parse source to map", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void readFrom(DataInput in) throws IOException, ClassNotFoundException {
|
||||
index = in.readUTF();
|
||||
type = in.readUTF();
|
||||
|
|
|
@ -19,19 +19,23 @@
|
|||
|
||||
package org.elasticsearch.action.index;
|
||||
|
||||
import org.elasticsearch.ElasticSearchGenerationException;
|
||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.action.support.replication.ShardReplicationOperationRequest;
|
||||
import org.elasticsearch.util.Required;
|
||||
import org.elasticsearch.util.TimeValue;
|
||||
import org.elasticsearch.util.Unicode;
|
||||
import org.elasticsearch.util.io.FastByteArrayOutputStream;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.action.Actions.*;
|
||||
import static org.elasticsearch.util.json.Jackson.*;
|
||||
|
||||
/**
|
||||
* Index request to index a typed JSON document into a specific index and make it searchable. Best
|
||||
|
@ -190,6 +194,22 @@ public class IndexRequest extends ShardReplicationOperationRequest {
|
|||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the JSON as a {@link Map}.
|
||||
*
|
||||
* @param source The map to index
|
||||
*/
|
||||
@Required public IndexRequest source(Map source) throws ElasticSearchGenerationException {
|
||||
FastByteArrayOutputStream os = FastByteArrayOutputStream.Cached.cached();
|
||||
try {
|
||||
defaultObjectMapper().writeValue(os, source);
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchGenerationException("Failed to generate [" + source + "]", e);
|
||||
}
|
||||
this.source = os.copiedByteArray();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the JSON source to index.
|
||||
*
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.search;
|
||||
|
||||
import org.apache.lucene.search.Explanation;
|
||||
import org.elasticsearch.ElasticSearchParseException;
|
||||
import org.elasticsearch.util.io.Streamable;
|
||||
import org.elasticsearch.util.json.ToJson;
|
||||
|
||||
|
@ -58,6 +59,11 @@ public interface SearchHit extends Streamable, ToJson, Iterable<SearchHitField>
|
|||
*/
|
||||
String sourceAsString();
|
||||
|
||||
/**
|
||||
* The source of the document as a map (can be <tt>null</tt>).
|
||||
*/
|
||||
Map<String, Object> sourceAsMap() throws ElasticSearchParseException;
|
||||
|
||||
/**
|
||||
* If enabled, the explanation of the search hit.
|
||||
*/
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.search.internal;
|
|||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.apache.lucene.search.Explanation;
|
||||
import org.elasticsearch.ElasticSearchParseException;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.SearchHitField;
|
||||
import org.elasticsearch.search.SearchShardTarget;
|
||||
|
@ -36,6 +37,7 @@ import java.util.Map;
|
|||
|
||||
import static org.elasticsearch.search.SearchShardTarget.*;
|
||||
import static org.elasticsearch.search.internal.InternalSearchHitField.*;
|
||||
import static org.elasticsearch.util.json.Jackson.*;
|
||||
import static org.elasticsearch.util.lucene.Lucene.*;
|
||||
|
||||
/**
|
||||
|
@ -89,6 +91,17 @@ public class InternalSearchHit implements SearchHit {
|
|||
return Unicode.fromBytes(source);
|
||||
}
|
||||
|
||||
@Override public Map<String, Object> sourceAsMap() throws ElasticSearchParseException {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return defaultObjectMapper().readValue(source, 0, source.length, Map.class);
|
||||
} catch (Exception e) {
|
||||
throw new ElasticSearchParseException("Failed to parse source to map", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public Iterator<SearchHitField> iterator() {
|
||||
return fields.values().iterator();
|
||||
}
|
||||
|
|
|
@ -31,6 +31,27 @@ import java.util.Arrays;
|
|||
*/
|
||||
public class FastByteArrayOutputStream extends OutputStream {
|
||||
|
||||
/**
|
||||
* A thread local based cache of {@link FastByteArrayOutputStream}.
|
||||
*/
|
||||
public static class Cached {
|
||||
|
||||
private static final ThreadLocal<FastByteArrayOutputStream> cache = new ThreadLocal<FastByteArrayOutputStream>() {
|
||||
@Override protected FastByteArrayOutputStream initialValue() {
|
||||
return new FastByteArrayOutputStream();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the cached thread local byte stream, with its internal stream cleared.
|
||||
*/
|
||||
public static FastByteArrayOutputStream cached() {
|
||||
FastByteArrayOutputStream os = cache.get();
|
||||
os.reset();
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The buffer where data is stored.
|
||||
*/
|
||||
|
@ -82,15 +103,14 @@ public class FastByteArrayOutputStream extends OutputStream {
|
|||
* Writes <code>len</code> bytes from the specified byte array
|
||||
* starting at offset <code>off</code> to this byte array output stream.
|
||||
*
|
||||
* <b>NO checks for bounds, parameters must be ok!</b>
|
||||
*
|
||||
* @param b the data.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of bytes to write.
|
||||
*/
|
||||
public void write(byte b[], int off, int len) {
|
||||
if ((off < 0) || (off > b.length) || (len < 0) ||
|
||||
((off + len) > b.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0) {
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
int newcount = count + len;
|
||||
|
|
|
@ -37,6 +37,8 @@ import org.testng.annotations.AfterMethod;
|
|||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.client.Requests.*;
|
||||
import static org.elasticsearch.index.query.json.JsonQueryBuilders.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
|
@ -101,6 +103,7 @@ public class DocumentActionsTests extends AbstractServersTests {
|
|||
for (int i = 0; i < 5; i++) {
|
||||
getResult = client1.get(getRequest("test").type("type1").id("1").threadedOperation(false)).actionGet();
|
||||
assertThat("cycle #" + i, getResult.sourceAsString(), equalTo(source("1", "test")));
|
||||
assertThat("cycle(map) #" + i, (String) ((Map) getResult.sourceAsMap().get("type1")).get("name"), equalTo("test"));
|
||||
getResult = client1.get(getRequest("test").type("type1").id("1").threadedOperation(true)).actionGet();
|
||||
assertThat("cycle #" + i, getResult.sourceAsString(), equalTo(source("1", "test")));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue