Skip to main content

Indexes: 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();