I am new to using map/reduce indexes so my question might be obvious, but I want to count the number of documents where a specific field has a specific value using a map/reduce index.
Let's say that I have documents with a field called activated
that can be either true
or false
. I know I can count all the documents, using the Sum
in the reduce function, but how to I make that Sum
only happen when activated
is true
?
Here is an example of such document created each time a user opens a session:
{
"userId": "user1",
"activated": true,
"loginDuration": 123
}
In Studio, I have created the following map
function:
from user in docs.Users
select new {
user.userId,
Count = 1,
user.loginDuration,
AvgLoginDuration = 0
}
and the reduce
function:
from r in results
group r by new r.userId into g
let totalLoginDuration = g.Sum(x => x.loginDuration)
let count = g.Sum(x => x.Count)
select new
{
userId = g.Key.userId,
Count = count,
TotalLoginDuration = totalLoginDuration,
AvgLoginDuration = totalLoginDuration / count
}
I would like to add to the map/reduce index a count of when activated
is true
, but don't know how to do that.
I have tried doing this:
from user in docs.Users
select new {
user.userId,
user.activated,
Count = 1,
user.loginDuration,
AvgLoginDuration = 0,
NumActivated = 0
}
from r in results
group r by new r.userId into g
let totalLoginDuration = g.Sum(x => x.loginDuration)
let count = g.Sum(x => x.Count)
select new
{
userId = g.Key.userId,
activated = g.Key.activated,
Count = count,
TotalLoginDuration = totalLoginDuration,
AvgLoginDuration = totalLoginDuration / count,
NumActivated = g.Sum(x => x.activated == true)
}
but it doesn't save and then I tried this:
from user in docs.Users
select new {
user.userId,
Count = 1,
user.loginDuration,
AvgLoginDuration = 0,
NumActivated = user.activated == true ? 1 : 0
}
from r in results
group r by new r.userId into g
let totalLoginDuration = g.Sum(x => x.loginDuration)
let count = g.Sum(x => x.Count)
select new
{
userId = g.Key.userId,
Count = count,
TotalLoginDuration = totalLoginDuration,
AvgLoginDuration = totalLoginDuration / count,
NumActivated = g.Sum(x => x.NumActivated == 1)
}
which saves, but then creates an error when the index is run saying it can't convert bool to decimal. How can I make this work?
Thanks a lot in advance, Bertrand.
Seems all you need to do is control the 'Count' in the Map part of the index.
Logic such as:
If activated is 0 the document will Not be counted in the reduce phase.
Here is some example that follows a similar logic: