计算RavenDB中的级联差异

时间:2014-12-08 12:34:11

标签: asp.net-mvc-4 ravendb

我正面临一个索引问题,但我还没有找到解决方案。

我每个主板都有以下文档结构:

{
    "Name": "Test Board",
    ...
    "Settings": {
        "Admins": [ "USER1", "USER2" ],
        "Members": [ "USER3", "USER4", "USER5" ]
        ...
    },
    ...
    "CreatedBy": "USER1",
    "CreatedOn": "2014-09-26T18:14:20.0858945"
    ...
}

现在我希望能够检索在董事会中注册的所有用户的数量。当然,这不仅应计算用户出现次数,还要计算不同用户的数量。一个用户可以是多个板的成员。

此操作应尽可能快地执行,因为它显示在每页上可见的全局统计信息板中。因此,我选择使用索引进行尝试,而不是检索所有主板及其用户,并在客户端进行工作。

尝试使用Map / Reduce索引实现此目的:

Map = boards => from board in boards
    select new
    {
        Aggregation = "ALL",
        Users = new object[]
        {
            board.CreatedBy,
            board.Settings.Admins,
            board.Settings.Members
        },
        NumberOfUsers = 1
    };

Reduce = results => from res in results
    group res by new
    {
        res.Aggregation
    }
    into g
    select new
    {
        g.Key.Aggregation,
        Users = g.Select(x => x.Users),
        NumberOfUsers = g.Sum(x => x.Users.Length)
    };

显然这会导致计数错误。我对Reduce没有任何经验,所以我很感激任何提示!解决方案可能很简单......

全局区分CreatedBy,管理员和所有文档的成员以及返回计数的最佳方式是什么?

提前致谢!

3 个答案:

答案 0 :(得分:0)

使用这样的索引:

from board in docs.Boards
select new 
{
    Users = board.Settings.Admins.Count + board.Settings.Members.Count + 1 /* created by */ 
}

from r in results
group r by "all" into g
select new
{
    Users = g.Sum(x=>x.Users)
}

答案 1 :(得分:0)

到目前为止我能说的最好的是:

Map = boards => from board in boards
    select new
    {
        Users = new object[]
        {
            board.CreatedBy,
            board.Settings.Admins,
            board.Settings.Members
        }
    };

Reduce = results => from r in results
    group r by "all" into g
    select new
    {
        Users = g.SelectMany(x => x.Users)
    };

然后查询不同的用户数:

var allUsersQuery = _documentSession.Query<AllUsersIndex.Result, AllUsersIndex>();
return allUsersQuery.Any() ? allUsersQuery.First().Users.Distinct().Count() : 0;

至少查询只返回所有板上所有用户名的列表,而不是更大的对象树。但是,必须在客户端完成唯一性。

如果有更好的方法请告诉我。只从服务器返回一个整数就很漂亮了......

答案 2 :(得分:0)

然后使用:

from board in docs.Boards
from user in board.Settings.Admins.Concat(board.Settings.Members).Concat(new[]{board.CreatedBy})
select new 
{
   User = user,
   Count = 1
}

from r in results
group r by r.User into g
select new
{
    User = g.Key,
    Count = g.Sum(x=>x.Count)
}

我对扇出不是很满意,但这会给你所有的discint用户和他们出现的次数。 如果您只想要不同用户的数量,只需从索引中获取总结果。