Indexes: Indexing Counters


  • To index counters, create a static index that inherits from AbstractCountersIndexCreationTask.

  • Auto-indexes for counters are not available at this time.

  • In this page:


Syntax

In order to index counter values, create an index that inherits from AbstractCountersIndexCreationTask. Next, choose one of these two methods which take the index expression:

protected void AddMapForAll(Expression<Func<IEnumerable<CounterEntry>, IEnumerable>> map)

protected void AddMap(string counter, Expression<Func<IEnumerable<CounterEntry>, IEnumerable>> map)

AddMapForAll indexes all the counters in the indexed documents. AddMap only indexes the counters with the specified name.

Examples of indexes using each method:

private class MyCounterIndex : AbstractCountersIndexCreationTask<Company>
{
    public MyCounterIndex()
    {
        AddMap("Likes", counters => from counter in counters
                                        select new
                                        {
                                            Likes = counter.Value,
                                            Name = counter.Name,
                                            User = counter.DocumentId
                                        });
    }
}
private class MyCounterIndex_AllCounters : AbstractCountersIndexCreationTask<Company>
{
    public MyCounterIndex_AllCounters()
    {
        AddMapForAll(counters => from counter in counters
                                 select new
                                 {
                                     Count = counter.Value,
                                     Name = counter.Name,
                                     User = 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:

IEnumerable<string> CounterNamesFor(object doc);

Example of index using CounterNamesFor:

public class Companies_ByCounterNames : AbstractIndexCreationTask<Company>
{
    public class Result
    {
        public string[] CounterNames { get; set; }
    }

    public Companies_ByCounterNames()
    {
        Map = employees => from e in employees
                           let counterNames = CounterNamesFor(e)
                           select new Result
                           {
                               CounterNames = counterNames.ToArray()
                           };
    }
}

Querying the Index

// return all companies that have 'Likes' counter
List<Company> companies = session
    .Query<Companies_ByCounterNames.Result, Companies_ByCounterNames>()
    .Where(x => x.CounterNames.Contains("Likes"))
    .OfType<Company>()
    .ToList();
// return all companies that have 'Likes' counter
List<Company> companies = await asyncSession
    .Query<Companies_ByCounterNames.Result, Companies_ByCounterNames>()
    .Where(x => x.CounterNames.Contains("Likes"))
    .OfType<Company>()
    .ToListAsync();
// return all companies that have 'Likes' counter
List<Company> companies = session
    .Advanced
    .DocumentQuery<Company, Companies_ByCounterNames>()
    .ContainsAny("CounterNames", new[] { "Likes" })
    .ToList();