Get Counters Operation

This operation is used to get counters' values for a specific document.
It can be used to get the value of a single counter, multiple counters' values, or all counters' values.

Syntax

GetCountersOperation

Use GetCountersOperation to get counters.
Find usage examples below for getting a single counter, multiple counters, or all document counters.

class GetCountersOperation {
    public function __construct(?string $docId, string|StringArray|array|null $counters = 
        null, bool $returnFullResults = false) { ... }
}
Parameters
docId string The ID of the document that holds the counters
counter string or StringArray or array or null The name or names array of the counter/s to get,
or null for all document counters
returnFullResults bool A flag which indicates if the operation should include a dictionary of counter values per database node in the result

Get Single Counter

$docId = "users/1";
$counter = "likes";
$returnFullResults = false;

$operation = new GetCountersOperation($docId, $counter, $returnFullResults);
Parameters
docId string The ID of the document that holds the counters
counter string The name of the counter to get
returnFullResults bool A flag which indicates if the operation should include a dictionary of counter values per database node in the result

Return Full Results flag:

If RavenDB is running in a distributed cluster, and the database resides on several nodes, a counter can have a different local value on each database node, and the total counter value is the sum of all the local values of this counter from each node.
In order to get the counter values per database node, set the returnFullResults flag to true


Get Multiple Counters

$docId = "users/1";
$counters = [ "likes", "score"];
$returnFullResults = false;

$operation = new GetCountersOperation($docId, $counters, $returnFullResults);
Parameters
docId string The ID of the document that holds the counters
counters StringArray or array The names of the counters to get
returnFullResults bool A flag which indicates if the operation should include a dictionary of counter values per database node in the result

Get All Counters of a Document

$docId = "users/1";
$returnFullResults = false;

$operation = new GetCountersOperation($docId, null, $returnFullResults);
Parameters
docId string The ID of the document that holds the counters
returnFullResults bool A flag which indicates if the operation should include a dictionary of counter values per database node in the result

Return Value

The operation returns a CountersDetail object, which holds a list of CounterDetail objects

class CountersDetail
{
    private ?CounterDetailList $counters = null;
}

class CounterDetail
{
    private ?string $documentId = null;     // ID of the document that holds the counter
    private ?string $counterName = null;    // The counter name
    private ?int $totalValue = null;        // Total counter value
    private ?int $etag = null;              // Counter Etag
    private ?array $counterValues = [];     // A dictionary of counter values per database node

    private ?string $changeVector = null;   // Change vector of the counter

    // ... getters and setters
}

class CounterDetailList extends TypedList
{
    public function __construct()
    {
        parent::__construct(CounterDetail::class);
        $this->setNullAllowed(true);
    }
}

Examples

Assume we have a users/1 document that holds 3 counters:
likes, dislikes and downloads - with values 10, 20 and 30 (respectively)

Example #1 : Get single counter

/** @var CountersDetail  $operationResult */
$operationResult = $store
    ->operations()
    ->send(new GetCountersOperation("users/1", "likes"));

Result:

{
	"Counters": 
    [
		{
			"DocumentId" : "users/1",
			"CounterName" : "likes",
			"TotalValue" : 10,
			"CounterValues" : null
		}
	]
}

Example #2 : Get multiple counters

/** @var CountersDetail $operationResult */
$operationResult = $store
    ->operations()
    ->send(new GetCountersOperation("users/1", [ "likes", "dislikes" ]));

Result:

{
	"Counters": 
    [
		{
			"DocumentId" : "users/1",
			"CounterName" : "likes",
			"TotalValue" : 10,
			"CounterValues" : null
		},
        {
			"DocumentId" : "users/1",
			"CounterName" : "dislikes",
			"TotalValue" : 20,
			"CounterValues" : null
		}
	]
}

Example #3 : Get all counters

/** @var CountersDetail $operationResult */
$operationResult = $store->operations()
    ->send(new GetCountersOperation("users/1"));

Result:

{
	"Counters": 
    [
		{
			"DocumentId" : "users/1",
			"CounterName" : "likes",
			"TotalValue" : 10,
			"CounterValues" : null
		},
        {
			"DocumentId" : "users/1",
			"CounterName" : "dislikes",
			"TotalValue" : 20,
			"CounterValues" : null
		},
        {
			"DocumentId" : "users/1",
			"CounterName" : "downloads",
			"TotalValue" : 30,
			"CounterValues" : null
		}
	]
}

Example #4 : Include full values in the result

/** @var CountersDetail $operationResult */
$operationResult = $store
    ->operations()
    ->send(new GetCountersOperation("users/1", "likes", true));

Result:

Assuming a 3-node cluster, the distribution of the counter's value to nodes A, B, and C could be as follows:

{
	"Counters": 
    [
		{
			"DocumentId" : "users/1",
			"CounterName" : "likes",
			"TotalValue" : 10,
			"CounterValues" : 
            {
                "A:35-UuCp420vs0u+URADcGVURA" : 5,
                "B:83-SeCFU29daUOxfjUcAlLiJw" : 3,
                "C:27-7i7GP8bOOkGYLNflO/rSeg" : 2,
            }
		}
	]
}