diff --git a/doc/3/controllers/document/count/index.md b/doc/3/controllers/document/count/index.md new file mode 100644 index 00000000..7be36d87 --- /dev/null +++ b/doc/3/controllers/document/count/index.md @@ -0,0 +1,53 @@ +--- +code: true +type: page +title: count +description: Counts documents in a collection. +--- + +# count + +Counts documents in a collection. + +A query can be provided to alter the count result, otherwise returns the total number of documents in the collection. + +Kuzzle uses the [ElasticSearch Query DSL](https://www.elastic.co/guide/en/elasticsearch/reference/7.4/query-dsl.html) syntax. + +--- + +## Arguments + +```java +public CompletableFuture count( + final String index, + final String collection) +throws NotConnectedException, InternalException + +``` + +```java +public CompletableFuture count( + final String index, + final String collection, + final ConcurrentHaspMap searchQuery) +throws NotConnectedException, InternalException + +``` + +--- + +| Argument | Type | Description | +| ------------------ | -------------------------------------------- | --------------- | +| `index` |
String
| Index name | +| `collection` |
String
| Collection name | +| `searchQuery` |
ConcurrentHashMap
| Query to match | + +--- + +## Return + +Returns an Integer. + +## Usage + +<<< ./snippets/count.java diff --git a/doc/3/controllers/document/count/snippets/count.java b/doc/3/controllers/document/count/snippets/count.java new file mode 100644 index 00000000..9fd3ad56 --- /dev/null +++ b/doc/3/controllers/document/count/snippets/count.java @@ -0,0 +1,8 @@ + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + Integer result = kuzzle + .getDocumentController() + .count("nyc-open-data", "yellow-taxi", searchQuery) + .get(); \ No newline at end of file diff --git a/doc/3/controllers/document/count/snippets/count.test.yml b/doc/3/controllers/document/count/snippets/count.test.yml new file mode 100644 index 00000000..4e7b4670 --- /dev/null +++ b/doc/3/controllers/document/count/snippets/count.test.yml @@ -0,0 +1,18 @@ +--- +name: document#count +description: Counts documents matching the given 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 '{"Hello": "Clarisse"}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + done + for i in 1 2 3 4 5; do + curl -H "Content-type: application/json" -d '{}' kuzzle:7512/nyc-open-data/yellow-taxi/_create + done + curl -XPOST kuzzle:7512/nyc-open-data/yellow-taxi/_refresh + after: +template: print-result +expected: 5 \ No newline at end of file diff --git a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java index 5ecd9e1f..abd29e69 100644 --- a/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java +++ b/src/main/java/io/kuzzle/sdk/API/Controllers/DocumentController.java @@ -1,5 +1,6 @@ package io.kuzzle.sdk.API.Controllers; +import com.google.gson.internal.LazilyParsedNumber; import io.kuzzle.sdk.CoreClasses.Maps.KuzzleMap; import io.kuzzle.sdk.Exceptions.InternalException; import io.kuzzle.sdk.Exceptions.NotConnectedException; @@ -593,4 +594,51 @@ public CompletableFuture>> mCreateOr return this.mCreateOrReplace(index, collection, documents, null); } + + /** + * Counts documents in a collection. + * + * @param index + * @param collection + * @paran searchQuery + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture count( + final String index, + final String collection, + final ConcurrentHashMap searchQuery) throws NotConnectedException, InternalException { + + final KuzzleMap query = new KuzzleMap(); + query + .put("index", index) + .put("collection", collection) + .put("controller", "document") + .put("body", new KuzzleMap().put("query", searchQuery)) + .put("action", "count"); + + return kuzzle + .query(query) + .thenApplyAsync( + (response) -> ((LazilyParsedNumber) ((ConcurrentHashMap)response.result).get("count")).intValue()); + } + + /** + * Counts documents in a collection. + * + * @param index + * @param collection + * @return a CompletableFuture + * @throws NotConnectedException + * @throws InternalException + */ + public CompletableFuture count( + final String index, + final String collection) throws NotConnectedException, InternalException { + + final ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + + return this.count(index, collection, searchQuery); + } } diff --git a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java index ee3a3950..ceb110e9 100644 --- a/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java +++ b/src/test/java/io/kuzzle/test/API/Controllers/DocumentTest/DocumentTest.java @@ -814,4 +814,59 @@ public void mCreateOrReplaceDocumentShouldThrowWhenNotConnected() throws NotConn kuzzleMock.getDocumentController().mCreateOrReplace(index, collection, documents); } + + @Test + public void countDocumentTestA() 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().count(index, collection); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "count"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + } + + @Test + public void countDocumentTestB() throws NotConnectedException, InternalException { + + Kuzzle kuzzleMock = spy(new Kuzzle(networkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + ArgumentCaptor arg = ArgumentCaptor.forClass(KuzzleMap.class); + + ConcurrentHashMap searchQuery = new ConcurrentHashMap<>(); + ConcurrentHashMap match = new ConcurrentHashMap<>(); + match.put("Hello", "Clarisse"); + searchQuery.put("match", match); + + kuzzleMock.getDocumentController().count(index, collection, searchQuery); + Mockito.verify(kuzzleMock, Mockito.times(1)).query(arg.capture()); + + assertEquals((arg.getValue()).getString("controller"), "document"); + assertEquals((arg.getValue()).getString("action"), "count"); + assertEquals((arg.getValue()).getString("index"), "nyc-open-data"); + assertEquals((arg.getValue()).getString("collection"), "yellow-taxi"); + assertEquals(((ConcurrentHashMap)((ConcurrentHashMap)(((KuzzleMap)(arg.getValue()).get("body"))).get("query")).get("match")).get("Hello"), "Clarisse"); + + } + + @Test(expected = NotConnectedException.class) + public void countDocumentShouldThrowWhenNotConnected() throws NotConnectedException, InternalException { + AbstractProtocol fakeNetworkProtocol = Mockito.mock(WebSocket.class); + Mockito.when(fakeNetworkProtocol.getState()).thenAnswer((Answer) invocation -> ProtocolState.CLOSE); + + Kuzzle kuzzleMock = spy(new Kuzzle(fakeNetworkProtocol)); + String index = "nyc-open-data"; + String collection = "yellow-taxi"; + + kuzzleMock.getDocumentController().count(index, collection); + } }