forked from searchbox-io/Jest
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request searchbox-io#520 from gilbode/update_by_query
Update by query
- Loading branch information
Showing
4 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
72 changes: 72 additions & 0 deletions
72
jest-common/src/main/java/io/searchbox/core/UpdateByQuery.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package io.searchbox.core; | ||
|
||
import com.google.gson.Gson; | ||
import io.searchbox.action.AbstractAction; | ||
import io.searchbox.action.AbstractMultiTypeActionBuilder; | ||
import java.util.Objects; | ||
|
||
/** | ||
* @author Lior Knaany | ||
*/ | ||
public class UpdateByQuery extends AbstractAction<UpdateByQueryResult> { | ||
|
||
protected UpdateByQuery(Builder builder) { | ||
super(builder); | ||
|
||
this.payload = builder.payload; | ||
setURI(buildURI()); | ||
} | ||
|
||
@Override | ||
protected String buildURI() { | ||
return super.buildURI() + "/_update_by_query"; | ||
} | ||
|
||
@Override | ||
public String getPathToResult() { | ||
return "ok"; | ||
} | ||
|
||
@Override | ||
public String getRestMethodName() { | ||
return "POST"; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(super.hashCode()); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (obj == null) { | ||
return false; | ||
} | ||
if (obj == this) { | ||
return true; | ||
} | ||
if (obj.getClass() != getClass()) { | ||
return false; | ||
} | ||
|
||
return super.equals(obj); | ||
} | ||
|
||
@Override | ||
public UpdateByQueryResult createNewElasticSearchResult(String responseBody, int statusCode, String reasonPhrase, Gson gson) { | ||
return createNewElasticSearchResult(new UpdateByQueryResult(gson), responseBody, statusCode, reasonPhrase, gson); | ||
} | ||
|
||
public static class Builder extends AbstractMultiTypeActionBuilder<UpdateByQuery, Builder> { | ||
|
||
private Object payload; | ||
|
||
public Builder(Object payload) {this.payload = payload;} | ||
|
||
@Override | ||
public UpdateByQuery build() { | ||
return new UpdateByQuery(this); | ||
} | ||
} | ||
|
||
} |
68 changes: 68 additions & 0 deletions
68
jest-common/src/main/java/io/searchbox/core/UpdateByQueryResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package io.searchbox.core; | ||
|
||
import com.google.gson.Gson; | ||
import com.google.gson.JsonArray; | ||
import io.searchbox.client.JestResult; | ||
|
||
/** | ||
* Created by Lior Knaany on 12/26/16. | ||
*/ | ||
public class UpdateByQueryResult extends JestResult { | ||
|
||
public UpdateByQueryResult(Gson gson) { | ||
super(gson); | ||
} | ||
|
||
public boolean didTimeOut() { | ||
return (jsonObject != null && jsonObject.has("timed_out")) ? jsonObject.get("timed_out").getAsBoolean() : false; | ||
} | ||
|
||
public long getConflictsCount() { | ||
return (jsonObject != null && jsonObject.has("version_conflicts")) ? jsonObject.get("version_conflicts").getAsLong() : 0L; | ||
} | ||
|
||
public long getMillisTaken() { | ||
return (jsonObject != null && jsonObject.has("took")) ? jsonObject.get("took").getAsLong() : 0L; | ||
} | ||
|
||
public long getUpdatedCount() { | ||
return (jsonObject != null && jsonObject.has("updated")) ? jsonObject.get("updated").getAsLong() : 0L; | ||
} | ||
|
||
public int getBatchCount() { | ||
return (jsonObject != null && jsonObject.has("batches")) ? jsonObject.get("batches").getAsInt() : 0; | ||
} | ||
|
||
public int getRetryCount() { | ||
return getBulkRetryCount() + getSearchRetryCount(); | ||
} | ||
|
||
public int getBulkRetryCount() { | ||
return (jsonObject != null && jsonObject.has("retries") && jsonObject.getAsJsonObject("retries").has("bulk")) ? jsonObject.getAsJsonObject("retries").get("bulk").getAsInt() : 0; | ||
} | ||
|
||
public int getSearchRetryCount() { | ||
return (jsonObject != null && jsonObject.has("retries") && jsonObject.getAsJsonObject("retries").has("search")) ? jsonObject.getAsJsonObject("retries").get("search").getAsInt() : 0; | ||
} | ||
|
||
public int getNoopCount() { | ||
return (jsonObject != null && jsonObject.has("noops")) ? jsonObject.get("noops").getAsInt() : 0; | ||
} | ||
|
||
public JsonArray getFailures() { | ||
return (jsonObject != null && jsonObject.has("failures")) ? jsonObject.get("failures").getAsJsonArray() : null; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Updated: " + getUpdatedCount() | ||
+ ", conflicts: " + getConflictsCount() | ||
+ ", time taken: " + getMillisTaken() | ||
+ ", did time out: " + didTimeOut() | ||
+ ", batches: " + getBatchCount() | ||
+ ", retries: " + getRetryCount() | ||
+ ", bulk retries: " + getBulkRetryCount() | ||
+ ", search retries: " + getSearchRetryCount() | ||
+ ", noops: " + getNoopCount(); | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
jest-common/src/test/java/io/searchbox/core/UpdateByQueryTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package io.searchbox.core; | ||
|
||
import org.junit.Test; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNotEquals; | ||
|
||
/** | ||
* @author Lior Knaany | ||
*/ | ||
public class UpdateByQueryTest { | ||
|
||
@Test | ||
public void getURIWithoutIndexAndType() { | ||
assertEquals("_all/_update_by_query", new UpdateByQuery.Builder(null).build().getURI()); | ||
} | ||
|
||
@Test | ||
public void getURIWithOnlyOneIndex() { | ||
assertEquals("twitter/_update_by_query", new UpdateByQuery.Builder(null).addIndex("twitter").build().getURI()); | ||
} | ||
|
||
@Test | ||
public void getURIWithOnlyMultipleType() { | ||
assertEquals("_all/tweet%2Cjest/_update_by_query", new UpdateByQuery.Builder(null).addType("tweet").addType("jest").build().getURI()); | ||
} | ||
|
||
@Test | ||
public void getURIWithOneIndexAndOneType() { | ||
assertEquals("twitter/tweet/_update_by_query", new UpdateByQuery.Builder(null).addIndex("twitter").addType("tweet").build().getURI()); | ||
} | ||
|
||
@Test | ||
public void getURIWithOnlyMultipleIndex() { | ||
assertEquals("twitter%2Csearchbox/_update_by_query", | ||
new UpdateByQuery.Builder(null).addIndex("twitter").addIndex("searchbox").build().getURI()); | ||
} | ||
|
||
@Test | ||
public void getURIWithMultipleIndexAndTypes() { | ||
assertEquals("twitter%2Csearchbox/tweet%2Cjest/_update_by_query", new UpdateByQuery.Builder(null) | ||
.addIndex("twitter") | ||
.addIndex("searchbox") | ||
.addType("tweet") | ||
.addType("jest") | ||
.build() | ||
.getURI()); | ||
} | ||
|
||
@Test | ||
public void equals() { | ||
UpdateByQuery deleteUserKramer = new UpdateByQuery.Builder("{\"user\":\"kramer\"}") | ||
.addIndex("twitter") | ||
.addIndex("searchbox") | ||
.addType("tweet") | ||
.addType("jest") | ||
.build(); | ||
UpdateByQuery deleteUserKramerDuplicate = new UpdateByQuery.Builder("{\"user\":\"kramer\"}") | ||
.addIndex("twitter") | ||
.addIndex("searchbox") | ||
.addType("tweet") | ||
.addType("jest") | ||
.build(); | ||
|
||
assertEquals(deleteUserKramer, deleteUserKramerDuplicate); | ||
} | ||
|
||
@Test | ||
public void equalsReturnsFalseForDifferentQueries() { | ||
UpdateByQuery deleteUserKramer = new UpdateByQuery.Builder("{\"user\":\"kramer\"}") | ||
.addIndex("twitter") | ||
.addIndex("searchbox") | ||
.addType("tweet") | ||
.addType("jest") | ||
.build(); | ||
UpdateByQuery deleteUserJerry = new UpdateByQuery.Builder("{\"user\":\"jerry\"}") | ||
.addIndex("twitter") | ||
.addIndex("searchbox") | ||
.addType("tweet") | ||
.addType("jest") | ||
.build(); | ||
|
||
assertNotEquals(deleteUserKramer, deleteUserJerry); | ||
} | ||
|
||
} |
92 changes: 92 additions & 0 deletions
92
jest/src/test/java/io/searchbox/core/UpdateByQueryIntegrationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package io.searchbox.core; | ||
|
||
import com.google.gson.GsonBuilder; | ||
|
||
import io.searchbox.common.AbstractIntegrationTest; | ||
import io.searchbox.core.UpdateByQueryResult; | ||
import org.elasticsearch.action.DocWriteResponse; | ||
import org.elasticsearch.common.settings.Settings; | ||
import org.elasticsearch.index.query.BoolQueryBuilder; | ||
import org.elasticsearch.index.query.QueryBuilders; | ||
import org.elasticsearch.index.reindex.ReindexPlugin; | ||
import org.elasticsearch.plugins.Plugin; | ||
import org.elasticsearch.rest.RestStatus; | ||
import org.elasticsearch.test.ESIntegTestCase; | ||
import org.junit.Test; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
|
||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; | ||
|
||
|
||
/** | ||
* @author Lior Knaany | ||
*/ | ||
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.SUITE, numDataNodes = 1) | ||
public class UpdateByQueryIntegrationTest extends AbstractIntegrationTest { | ||
|
||
private static final String INDEX = "twitter"; | ||
private static final String TYPE = "tweet"; | ||
|
||
@Override | ||
protected Collection<Class<? extends Plugin>> nodePlugins() { | ||
final ArrayList<Class<? extends Plugin>> plugins = new ArrayList<>(super.nodePlugins()); | ||
plugins.add(ReindexPlugin.class); | ||
return plugins; | ||
} | ||
|
||
@Override | ||
protected Settings nodeSettings(int nodeOrdinal) { | ||
final Settings.Builder builder = Settings.builder().put(super.nodeSettings(nodeOrdinal)); | ||
return builder | ||
.put(super.nodeSettings(nodeOrdinal)) | ||
.put("script.inline", "true") | ||
.build(); | ||
} | ||
|
||
@Test | ||
public void update() throws IOException, InterruptedException { | ||
|
||
// create a tweet | ||
assertTrue(index(INDEX, TYPE, "1", "{\"user\":\"lior\",\"num\":1}").getResult().equals(DocWriteResponse.Result.CREATED)); | ||
assertTrue(index(INDEX, TYPE, "2", "{\"user\":\"kimchy\",\"num\":2}").getResult().equals(DocWriteResponse.Result.CREATED)); | ||
|
||
refresh(); | ||
ensureSearchable(INDEX); | ||
|
||
// run the search and update | ||
final BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("user", "lior")); | ||
final String script = "ctx._source.user = ctx._source.user + '_updated';"; | ||
|
||
final String payload = jsonBuilder() | ||
.startObject() | ||
.field("query", queryBuilder) | ||
.startObject("script") | ||
.field("inline", script) | ||
.endObject() | ||
.endObject().string(); | ||
|
||
UpdateByQuery updateByQuery = new UpdateByQuery.Builder(payload) | ||
.addIndex(INDEX) | ||
.addType(TYPE) | ||
.build(); | ||
|
||
UpdateByQueryResult result = client.execute(updateByQuery); | ||
|
||
// Checks | ||
assertTrue(result.getErrorMessage(), result.isSucceeded()); | ||
|
||
assertFalse(result.didTimeOut()); | ||
assertEquals(0, result.getConflictsCount()); | ||
assertTrue(result.getMillisTaken() > 0); | ||
assertEquals(1, result.getUpdatedCount()); | ||
assertEquals(0, result.getRetryCount()); | ||
assertEquals(0, result.getBulkRetryCount()); | ||
assertEquals(0, result.getSearchRetryCount()); | ||
assertEquals(0, result.getNoopCount()); | ||
assertEquals(0, result.getFailures().size()); | ||
} | ||
|
||
} |