Indexes: Indexing Counters



Syntax

To index counter values, create an index that inherits from AbstractCountersIndexCreationTask and set a map as follows.

class MyCounterIndex extends AbstractCountersIndexCreationTask
{
    public function __construct()
    {
        parent::__construct();

        $this->setMap(
            "from counter in counters " .
            "select new { " .
            "    Likes = counter.Value, " .
            "    Name = counter.Name, " .
            "    User = counter.DocumentId " .
            "}"
        );
    }
}

AbstractJavaScriptCountersIndexCreationTask

Creating an index inheriting from AbstractJavaScriptCountersIndexCreationTask allows you to write your map and reduce functions in JavaScript.
Learn more about JavaScript indexes here.

public class AbstractJavaScriptCountersIndexCreationTask : AbstractCountersIndexCreationTask
{
    public HashSet<string> Maps;
    protected string Reduce;
}
Property Type Description
Maps HashSet<string> The set of javascript map functions
Reduce string The javascript reduce function

Example:

class MyMultiMapCounterIndex extends AbstractJavaScriptCountersIndexCreationTask
{
    public function __construct()
    {
        parent::__construct();

        $this->setMaps([
            "counters.map('Blogposts', 'Likes', function (counter) {
                return {
                    Likes: counter.Value,
                    Name: counter.Name,
                    Blog Post: counter.DocumentId
                };
            })"
        ]);
    }
}

CounterNamesFor

While indexes inheriting from AbstractIndexCreationTask cannot index counter values, the CounterNamesFor method is available which returns the names of all counters for a specified document:

List<String> counterNamesFor(Object doc);

Example of index using CounterNamesFor:

class Companies_ByCounterNames_Result
{
    public ?StringArray $counterNames = null;

    public function getCounterNames(): ?StringArray
    {
        return $this->counterNames;
    }

    public function setCounterNames(?StringArray $counterNames): void
    {
        $this->counterNames = $counterNames;
    }
}
class Companies_ByCounterNames extends AbstractIndexCreationTask
{
    public function __construct()
    {
        parent::__construct();

        $this->map = "from e in docs.Employees " .
            "let counterNames = counterNamesFor(e) " .
            "select new {" .
            "    CounterNames = counterNames.ToArray() " .
            "}";
    }
}