Dot-Net

使用 .NET 客戶端的 RavenDB Map-Reduce 範例

  • November 23, 2010

我正在尋找如何在 RavenDB .NET 客戶端中實現和使用 Map-Reduce 的範例。

我想將其應用於特定場景:生成唯一的訪客總數和總訪客數。

將儲存在 RavenDB 中的範例文件:

public class StatisticsEntry
{
   public string Id { get; set; }
   public string UserId { get; set; }
}

我可以弄清楚如何使用 Map 創建標準索引,但我不知道如何實際使用 Reduce 函式,然後檢索結果。

不幸的是,RavenDB 站點上提供的範例沒有解釋發生了什麼,因此我可以理解如何通過 .NET API 使用它,並且範例似乎根本沒有使用 .NET API 實現這一點。

map reduce index 只是另一種說法“我想做一個 group by”,只有 group by 是預先定義好的,RavenDB 會在後台以有效的方式處理它,所以在查詢時你正在查找預先計算的結果。

將以下內容視為普通組的答案(針對唯一使用者)

var results = from doc in docs
group doc by doc.UserId into g
select new
{
     g.UserId,
     g.Count()
}

忽略創建數組的實際內容,我們可以通過詢問得到總的結果

results.Length

如您所料。

在 RavenDB 中,您將此函式拆分為 Map 和 Reduce,最終得到

public class UniqueVisitorsResult
{
    public string UserId { get; set; }
    public int Count { get; set; }
}

public class UniqueVisitorsIndex : AbstractIndexCreationTask<StatisticsEntry, UniqueVisitorsResult>
{
   public UniqueVisitorsIndex ()
   {
       Map = docs=> from doc in docs
                        select new 
                        { 
                            UserId = doc.UserId, 
                            Count = 1 
                        };
       Reduce = results => from result in results
                       group result by result.UserId into g
                       select new 
                       { 
                           UserId = g.Key, 
                           Count = g.Sum(x=>x.Count) 
                       };
   }
}

本質上,這和上面的一樣——但是你已經把它變成了一個 MapReduce 函式 ;-)

session.Query<StatisticEntry, UniqueVisitorsIndex>().Count();

假設 Count 已在 LINQ 提供程序中正確實施(我認為是 iirc),將為您提供唯一訪問者的總數

條目總數很簡單

session.Query<StatisticEntry>().Count();

如您所料(不需要 map/reduce)

注意:這個索引也可以用來查看特定使用者的點擊次數,因為計數是在索引中計算的,如果你不關心計數,那麼刪除 MapReduce 的那部分並執行

public class UniqueVisitorsIndex : AbstractIndexCreationTask<StatisticsEntry>
{
   public UniqueVisitorsIndex ()
   {
       Map = docs=> from doc in docs
                    select new 
                    { 
                        UserId = doc.UserId
                    };
       Reduce = results => from result in results
                   group result by result.UserId into g
                   select new 
                   { 
                       UserId = g.Key
                   };
   }
}

引用自:https://stackoverflow.com/questions/4253334