代码之家  ›  专栏  ›  技术社区  ›  ZVenue

LINQ查询以输出键计数值对

  •  2
  • ZVenue  · 技术社区  · 12 年前

    大约有50万份RavenDB客户文档。其中一处房产是“城市”。。我如何写一个LINQ查询来获得每个城市的所有出现及其计数的列表。例如,如果一千个客户文档的城市值为“NY”,那么我需要一个城市列表,其计数为NY 1000;LA 200、OR 1300、BO 5000等。。

    这是我最初写的。。

     Dictionary<string,int> cityStats = session.Query<Customer>()
                        .ToList()
                        .GroupBy(x => x.City)
                        .OrderBy(x => x.Count())
                        .ToDictionary(x => x.Key, x => x.Count());
    

    但这看起来并不能给我准确的结果。。所以我更改了maximum requests allowed属性(我知道这是不推荐的),只是想看看它是否会更改结果。。但将maxrequest值保持为500000也会给我带来同样的结果。我确信大约有50万份客户文档,所以需要加起来才能匹配。

    1 回复  |  直到 12 年前
        1
  •  2
  •   Matt Johnson-Pint    12 年前

    你需要一个地图减少索引来做到这一点。下面是一个简短的控制台程序,演示:

    using System;
    using System.Linq;
    using Raven.Client.Document;
    using Raven.Client.Indexes;
    
    namespace ConsoleApplication1
    {
      public class Customer
      {
        public string Id { get; set; }
        public string Name { get; set; }
        public string City { get; set; }
      }
    
      public class Customers_ByCity : AbstractIndexCreationTask<Customer, Customers_ByCity.Result>
      {
        public Customers_ByCity()
        {
          Map = customers => from customer in customers
                             select new
                             {
                               customer.City,
                               Count = 1
                             };
    
          Reduce = results => from result in results
                              group result by result.City
                              into g
                              select new
                              {
                                City = g.Key,
                                Count = g.Sum(x => x.Count)
                              };
        }
    
        public class Result
        {
          public string City { get; set; }
          public int Count { get; set; }
        }
      }
    
      class Program
      {
        private static void Main()
        {
          var documentStore = new DocumentStore { Url = "http://localhost:8080" };
          documentStore.Initialize();
          IndexCreation.CreateIndexes(typeof(Program).Assembly, documentStore);
    
          using (var session = documentStore.OpenSession())
          {
            session.Store(new Customer { Name = "John", City = "NY" });
            session.Store(new Customer { Name = "Jane", City = "NY" });
            session.Store(new Customer { Name = "Jim", City = "NY" });
            session.Store(new Customer { Name = "Sally", City = "LA" });
            session.Store(new Customer { Name = "Sam", City = "LA" });
            session.Store(new Customer { Name = "Suzie", City = "LA" });
            session.Store(new Customer { Name = "Sarah", City = "LA" });
    
            session.SaveChanges();
          }
    
          using (var session = documentStore.OpenSession())
          {
            // In a real app, you probably don't want to wait for nonstale results.
            // You will also want to consider what to do if you have more than one page of results (more than 1024 cities)
    
            var counts = session.Query<Customers_ByCity.Result, Customers_ByCity>()
              .Customize(x=> x.WaitForNonStaleResults())
              .Take(1024);
    
            foreach (var result in counts)
            {
              Console.WriteLine("{0}: {1}", result.City, result.Count);
            }
    
            Console.WriteLine();
          }
          Console.ReadLine();
        }
      }
    }