【问题标题】:RavenDB - Sift through documents and get count using index/queryRavenDB - 筛选文档并使用索引/查询获取计数
【发布时间】:2012-03-06 19:12:48
【问题描述】:

我有一个城市文件,站点文件。城市可以有多个站点。站点文档中包含城市信息。 RavenDB中大约有100个城市文档和10000个站点文档

城市文件:

{
    "CityCode": "NY",

    "CityName": "New York"
}

网站文件:

{
    "SiteName": "MOMA",

    "CityCode": "NY"
}

目标是获取所有城市的列表以及每个喜欢的站点数量...

City   Sites
NY     12
CH      33
BO      56
and so on....

我正在这样做。

int countSites = session.Query<Site>()
                        .Count();


var SiteCityList = session.Query<Site>()
                          .Take(countSites)
                          .ToList()
                          .GroupBy(x => x.CityCode)
                          .OrderBy(x => x.Count())
                          .ToDictionary(x => x.Key, x => x.Count());

这并没有给出 ravendb 中的所有数据。我在任何时候都只能得到 11 行的站点计数,甚至计数也不准确。我想要的是获得所有 100 个城市的列表以及每个城市的站点数量(以 100 为单位)作为列表,如上所示。感谢您的帮助。

【问题讨论】:

    标签: c# database linq nosql ravendb


    【解决方案1】:

    使用这样的 map/reduce 索引

    public class CityCodeCount : AbstractIndexCreationTask<Site, CityCodeCount.ReduceResult>
    {
        public class ReduceResult
        {
            public string CityCode { get; set; }
            public int Count { get; set; }
        }
    
        public CityCodeCount()
        {
            Map = sites => from site in sites
                            select new
                            {
                                site.CityCode,
                                Count = 1
                            };
    
            Reduce = results => from result in results
                                group result by result.CityCode
                                into g
                                select new
                                {
                                    CityCode = g.Key,
                                    Count = g.Sum(x => x.Count)
                                };
    
        }
    }
    

    之后,您可以轻松查询。

    var results = documentSession.Query<CityCodeCount.ReduceResult, CityCodeCount>()
        .ToList();
    

    【讨论】:

      【解决方案2】:

      如果你想要另一种方式,你可以看看Faceted Search

      与 Map/Reduce 相比,它为您提供了更多的灵活性,但仅在您需要 Count of items 时才有效(在您的情况下您会这样做)。

      【讨论】:

        【解决方案3】:

        你有两个选择:

        1. 创建Map/Reduce index 并对其进行查询
        2. 使用Faceted (Aggregated) Search查询

        要在两者之间做出选择,请考虑到

        • 专门的索引查询速度更快,但会占用一些存储空间和对更改记录重新编制索引的性能(如果您需要立即保持一致性并等待非陈旧索引,这可能很重要)。
        • 当您已经将字段覆盖在现有索引中时,Facet 更易于使用。我相信您了解静态索引的重要性并且已经掌握了一些。

        虽然使用 Map/Reduce 索引很简单,并且 Daniel 的回答已经涵盖,但我在下面提供了一个使用 Facets 的示例:

        var query = DbSession.Query<Site_IndexModel, Site_ForList>();
        List<FacetValue> facetResults = (await query
                                                .AggregateBy(builder => builder.ByField(s => s.CityCode ))
                                                .ExecuteAsync()
                                        ).Single().Value.Values;
        // Go through results, where each facetResult is { Range, Count } structure
        return  from result in facetResults
                select new { CityCode = result.Range, Count = result.Count }
        

        在哪里

        • Site_ForListSite 集合的现有索引,其中包括 CityCode 字段
        • Site_IndexModelSite_ForList索引的存储结构

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多