Skip to main content

Indexing Counters

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
});
}
}

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;
}
PropertyTypeDescription
MapsHashSet<string>The set of javascript map functions
ReducestringThe javascript reduce function

Example:

private class MyMultiMapCounterIndex : AbstractJavaScriptCountersIndexCreationTask
{
public MyMultiMapCounterIndex()
{
Maps = new HashSet<string>
{
@"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:

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();
In this article