Skip to content
This repository was archived by the owner on Sep 28, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .ci/doc/templates/print-result-arraylist.tpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import io.kuzzle.sdk.Kuzzle;
import io.kuzzle.sdk.Protocol.WebSocket;
import io.kuzzle.sdk.Options.Protocol.WebSocketOptions;
import io.kuzzle.sdk.Options.KuzzleOptions;
import io.kuzzle.sdk.Options.SubscribeOptions;
import io.kuzzle.sdk.CoreClasses.Responses.Response;

import java.util.concurrent.ConcurrentHashMap;
import java.util.ArrayList;

public class SnippetTest {
private static Kuzzle kuzzle;

public static void main(String[] argv) {
try {
kuzzle = new Kuzzle(new WebSocket("kuzzle"));
kuzzle.connect();
[snippet-code]
for (Object o : result) {
System.out.println(o);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (kuzzle != null) {
kuzzle.disconnect();
}
}
}
}
46 changes: 46 additions & 0 deletions doc/3/controllers/document/delete-by-query/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
code: true
type: page
title: deleteByQuery
description: Delete documents matching query
---

# deleteByQuery

Deletes documents matching the provided search query.

Kuzzle uses the [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl.html) syntax.

An empty or null query will match all documents in the collection.

<br/>

```java
public CompletableFuture<ArrayList<String>> deleteByQuery(
final String index,
final String collection,
final ConcurrentHashMap<String, Object> searchQuery) throws NotConnectedException, InternalException

public CompletableFuture<ArrayList<String>> deleteByQuery(
final String index,
final String collection,
final ConcurrentHashMap<String, Object> searchQuery,
final Boolean waitForRefresh) throws NotConnectedException, InternalException
```

| Argument | Type | Description |
| ------------------ | -------------------------------------------- | --------------- |
| `index` | <pre>String</pre> | Index name |
| `collection` | <pre>String</pre> | Collection name |
| `searchQuery` | <pre>ConcurrentHashMap<String, Object></pre> | Query to match |
| `waitForRefresh` | <pre>Boolean</pre> (optional) | If set to `true`, Kuzzle will wait for the persistence layer to finish indexing|

---

## Returns

Returns an `ArrayList<String>` containing the deleted document ids.

## Usage

<<< ./snippets/delete-by-query.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ConcurrentHashMap<String, Object> searchQuery = new ConcurrentHashMap<>();
ConcurrentHashMap<String, Object> query = new ConcurrentHashMap<>();
ConcurrentHashMap<String, Object> match = new ConcurrentHashMap<>();
match.put("capacity", 4);
query.put("match", match);
searchQuery.put("query", query);
ArrayList<String> result = kuzzle
.getDocumentController()
.deleteByQuery("nyc-open-data", "yellow-taxi", searchQuery)
.get();
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: document#deleteByQuery
description: Delete documents matching query
hooks:
before: |
curl -XDELETE kuzzle:7512/nyc-open-data
curl -XPOST kuzzle:7512/nyc-open-data/_create
curl -XPUT kuzzle:7512/nyc-open-data/yellow-taxi
for i in 1 2 3 4 5; do
curl -H "Content-type: application/json" -d '{"capacity": 4}' kuzzle:7512/nyc-open-data/yellow-taxi/document_$i/_create
done
for i in 1 2 3 4 5; do
curl -H "Content-type: application/json" -d '{"capacity": 7}' kuzzle:7512/nyc-open-data/yellow-taxi/_create
done
curl -XPOST kuzzle:7512/nyc-open-data/_refresh
after:
template: print-result-arraylist
expected:
- "document_1"
- "document_2"
- "document_3"
- "document_4"
- "document_5"
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,57 @@ public CompletableFuture<ConcurrentHashMap<String, ArrayList<Object>>> mCreateOr
return this.mCreateOrReplace(index, collection, documents, null);
}

/**
* Deletes documents matching the provided search query.
*
* @param index
* @param collection
* @param searchQuery
* @param waitForRefresh
* @return a CompletableFuture
* @throws NotConnectedException
* @throws InternalException
*/
public CompletableFuture<ArrayList<String>> deleteByQuery(
final String index,
final String collection,
final ConcurrentHashMap<String, Object> searchQuery,
final Boolean waitForRefresh) throws NotConnectedException, InternalException {

final KuzzleMap query = new KuzzleMap();

query
.put("index", index)
.put("collection", collection)
.put("controller", "document")
.put("action", "deleteByQuery")
.put("body", new KuzzleMap(searchQuery))
.put("waitForRefresh", waitForRefresh);

return kuzzle
.query(query)
.thenApplyAsync(
(response) -> (ArrayList<String>)((ConcurrentHashMap<String, Object>) response.result).get("ids"));
}

/**
* Deletes documents matching the provided search query.
*
* @param index
* @param collection
* @param searchQuery
* @return a CompletableFuture
* @throws NotConnectedException
* @throws InternalException
*/
public CompletableFuture<ArrayList<String>> deleteByQuery(
final String index,
final String collection,
final ConcurrentHashMap<String, Object> searchQuery) throws NotConnectedException, InternalException {

return this.deleteByQuery(index, collection, searchQuery, null);
}

/**
* Validates data against existing validation rules.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,37 @@ public class DocumentTest {

private AbstractProtocol networkProtocol = Mockito.mock(WebSocket.class);

@Test
public void getDocumentTest() throws NotConnectedException, InternalException {

Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol));
String index = "nyc-open-data";
String collection = "yellow-taxi";

ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class);

kuzzleMock.getDocumentController().get(index, collection, "some-id");
Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture());

assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document");
assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "get");
assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data");
assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id");
}

@Test(expected = NotConnectedException.class)
public void getDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException {
AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class);
Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer<ProtocolState>) invocation -> ProtocolState.CLOSE);

Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol));
String index = "nyc-open-data";
String collection = "yellow-taxi";

kuzzleMock.getDocumentController().get(index, collection, "some-id");
}


@Test
public void createDocumentTestA() throws NotConnectedException, InternalException {

Expand Down Expand Up @@ -82,7 +113,6 @@ public void createDocumentTestB() throws NotConnectedException, InternalExceptio

@Test(expected = NotConnectedException.class)
public void createDocumentThrowWhenNotConnected() throws NotConnectedException, InternalException {

AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class);
Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer<ProtocolState>) invocation -> ProtocolState.CLOSE);

Expand All @@ -97,36 +127,6 @@ public void createDocumentThrowWhenNotConnected() throws NotConnectedException,
kuzzleMock.getDocumentController().create(index, collection, document);
}

@Test
public void getDocumentTest() throws NotConnectedException, InternalException {

Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol));
String index = "nyc-open-data";
String collection = "yellow-taxi";

ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class);

kuzzleMock.getDocumentController().get(index, collection, "some-id");
Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture());

assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document");
assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "get");
assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data");
assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id");
}

@Test(expected = NotConnectedException.class)
public void getDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException {
AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class);
Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer<ProtocolState>) invocation -> ProtocolState.CLOSE);

Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol));
String index = "nyc-open-data";
String collection = "yellow-taxi";

kuzzleMock.getDocumentController().get(index, collection, "some-id");
}

@Test
public void createOrReplaceDocumentTestA() throws NotConnectedException, InternalException {

Expand Down Expand Up @@ -258,7 +258,24 @@ public void updateShouldThrowWhenNotConnected() throws NotConnectedException, In
ConcurrentHashMap<String, Object> document = new ConcurrentHashMap<>();
document.put("name", "Yoann");

kuzzleMock.getDocumentController().update(index, collection, id, document);
UpdateOptions options = new UpdateOptions();
options.setWaitForRefresh(false);
options.setSource(true);
options.setRetryOnConflict(1);

ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class);

kuzzleMock.getDocumentController().update(index, collection, "some-id", document, options);
Mockito.verify(kuzzleMock, Mockito.times(1)).query((KuzzleMap) arg.capture());

assertEquals(((KuzzleMap) arg.getValue()).getString("controller"), "document");
assertEquals(((KuzzleMap) arg.getValue()).getString("action"), "update");
assertEquals(((KuzzleMap) arg.getValue()).getString("index"), "nyc-open-data");
assertEquals(((KuzzleMap) arg.getValue()).getString("_id"), "some-id");
assertEquals(((KuzzleMap) arg.getValue()).getNumber("retryOnConflict"), 1);
assertEquals(((KuzzleMap) arg.getValue()).getBoolean("waitForRefresh"), false);
assertEquals(((KuzzleMap) arg.getValue()).getBoolean("source"), true);
assertEquals(((ConcurrentHashMap<String, Object>) (((KuzzleMap) arg.getValue()).get("body"))).get("name").toString(), "Yoann");
}

@Test
Expand Down Expand Up @@ -919,6 +936,75 @@ public void mCreateOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConn
kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents);
}

@Test
public void deleteByQueryDocumentTestA() throws NotConnectedException, InternalException {

Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol));
String index = "nyc-open-data";
String collection = "yellow-taxi";

ConcurrentHashMap<String, Object> searchQuery = new ConcurrentHashMap<>();
ConcurrentHashMap<String, Object> query = new ConcurrentHashMap<>();
ConcurrentHashMap<String, Object> match = new ConcurrentHashMap<>();
match.put("Hello", "Clarisse");
query.put("match", match);
searchQuery.put("query", query);

ArgumentCaptor<KuzzleMap> arg = ArgumentCaptor.forClass(KuzzleMap.class);

kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery);
Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture());

assertEquals((arg.getValue()).getString("controller"), "document");
assertEquals((arg.getValue()).getString("action"), "deleteByQuery");
assertEquals((arg.getValue()).getString("index"), "nyc-open-data");
assertEquals((arg.getValue()).getBoolean("waitForRefresh"), null);
assertEquals(((ConcurrentHashMap<String, Object>) ((ConcurrentHashMap<String, Object>) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse");
}

@Test
public void deleteByQueryDocumentTestB() throws NotConnectedException, InternalException {

Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol));
String index = "nyc-open-data";
String collection = "yellow-taxi";

ConcurrentHashMap<String, Object> searchQuery = new ConcurrentHashMap<>();
ConcurrentHashMap<String, Object> query = new ConcurrentHashMap<>();
ConcurrentHashMap<String, Object> match = new ConcurrentHashMap<>();
match.put("Hello", "Clarisse");
query.put("match", match);
searchQuery.put("query", query);

ArgumentCaptor<KuzzleMap> arg = ArgumentCaptor.forClass(KuzzleMap.class);

kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery, false);
Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture());

assertEquals((arg.getValue()).getString("controller"), "document");
assertEquals((arg.getValue()).getString("action"), "deleteByQuery");
assertEquals((arg.getValue()).getString("index"), "nyc-open-data");
assertEquals((arg.getValue()).getBoolean("waitForRefresh"), false);
assertEquals(((ConcurrentHashMap<String, Object>) ((ConcurrentHashMap<String, Object>) (((KuzzleMap) (arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse");
}

@Test(expected = NotConnectedException.class)
public void deleteByQueryDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException {
AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class);
Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer<ProtocolState>) invocation -> ProtocolState.CLOSE);

Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol));
String index = "nyc-open-data";
String collection = "yellow-taxi";

ConcurrentHashMap<String, Object> searchQuery = new ConcurrentHashMap<>();
ConcurrentHashMap<String, Object> match = new ConcurrentHashMap<>();
match.put("Hello", "Clarisse");
searchQuery.put("match", match);

kuzzleMock.getDocumentController().deleteByQuery(index, collection, searchQuery);
}

@Test
public void validateDocumentTest() throws NotConnectedException, InternalException {

Expand Down