2010-11-23 22 views
22

RavenDB .NET İstemcisi'nde Map-Reduce'un nasıl uygulanacağını ve kullanılacağını gösteren bir örnek arıyorum.RavenDB Map-Reduce Örneği .NET İstemcisi Kullanılıyor

Belirli bir senaryoyu uygulamak istiyorum: benzersiz ve toplam ziyaretçi sayısı oluşturmak. RavenDB içinde saklanan olacağını

Örnek bir belge:

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

Ben Haritası kullanarak standart bir dizin oluşturmak için nasıl anlamaya, ama aslında işlevini azaltın nasıl kullanılacağı konusunda kayboldum ve sonra sonuçları al.

Ne yazık ki, example provided on the RavenDB Site, neler olup bittiğini açıklamıyor, böylece .NET API'sı aracılığıyla nasıl kullanılacağını anlayabiliyorum ve örnekler bunu .NET API kullanarak hiç uygulamıyor gibi görünüyor.

public class Statistics_UniqueVisitors : AbstractIndexCreationTask<StatisticsEntry> 
{ 
    public Statistics_UniqueVisitors() 
    { 
     Map = entries => from entry in entries 
         select new { entry.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) }; 
    } 
} 

Ardından kullanarak bu sorgulayabilir: Burada

+0

Neyi başarmak istiyorsunuz? Tarih saatini herhangi bir şekilde kullanmak mı istiyorsunuz? (Günde, ayda, yılda, kinda şeyler?) –

+0

Şu anda yok. Bu alanı kullanarak daha sonra ek dizinlerim olabilir. Şimdilik, basitleştirmek için onu sınıftan kaldıracağım. "Kazanmak İstiyorum" konusuna gelince: - İstatistiklerin toplam sayımını gösterir.) İstatistiklerin Toplam sayısı ve b) Benzersiz Kullanıcılar. –

+0

Tamam - çünkü bu tür senaryoda 'gruplama' başına bir eşleme/azaltma endeksine ihtiyacınız olacaktır - bir –

cevap

38

Bir haritayı küçültmek, "Bir grupla yapmak istiyorum" ifadesinin başka bir yoludur, yalnızca grup önceden -defined up ve RavenDB arka planda verimli bir şekilde işleyecek, böylece sorgulama zamanında bir önceden hesaplanmış sonuca bakıyorsunuz.

oluşturulan dizinin gerçek içeriğini göz ardı edilmesi

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

(benzersiz kullanıcılar için) tarafından sıradan bir grup olarak bir cevap olarak aşağıdaki düşünün, biz

results.Length 
isteyerek toplam sonuçlar alabilirsiniz

beklediğiniz gibi.RavenDB yılında

, bir harita ve bir azaltın içine bu işlevini böler ve Özünde

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

ile bitirmek, bu yukarıdaki aynıdır - ama bir çevirdiniz MapReduce fonksiyonu ;-)

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

Kont varsayarak size tekil ziyaretçi sayısını verecek LINQ sağlayıcısına (iirc ben olduğunu düşünüyorum)

toplam düzgün uygulamaya konmuştur Eğer (No harita/gerekli azaltmak) Tahmin edeceğiniz gibi giriş sayısı sadece

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

olduğunu

Not: Bu indeks de Kont gibi belirli bir kullanıcı tarafından isabet sayısını görmek için kullanılabilir Eğer sayımı önemsemiyorsanız, o zaman MapReduce'un o kısmını bırakın ve

+0

Müthiş jiffy'de yanıt gelecektir. Açıklama için teşekkürler. –

+0

İlk örnekte 'Count = g.Sum (x => x.Count)' - sağlarsınız. Bu, 'x' türünün 'StatisticsEntry' olduğu bir derleme hatası verir - nereden gelmesi gerekiyor? –

+1

Oh, bir çıkış şekli tanımlayın, örneğimi değiştirmeme izin verin :) –

18

benzersiz ziyaretçiler için bir dizin oluşturabilirsiniz nasıl

var numberOfUniqueVisitors = s.Query<StatisticEntry, Statistics_UniqueVisitors>().Count(); 

toplam ziyaretçi sayısı için, kullanabilirsiniz:

var numberOfVisitors = s.Query<StatisticEntry>().Count();