RavenDB - Просеивать документы и подсчитывать, используя индекс / запрос - PullRequest
2 голосов
/ 06 марта 2012

У меня есть городской документ, документ сайта.Город может иметь несколько сайтов.Документ сайта содержит информацию о городе.В 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 городов и количество сайтов для каждого города (в сотнях) в виде списка, как показано выше.Спасибо за помощь.

Ответы [ 3 ]

3 голосов
/ 07 марта 2012

Используйте индекс карты / уменьшения как этот

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 голосов
/ 12 марта 2012

Если вы хотите альтернативный способ, вы можете взглянуть на Многогранный поиск

Это дает вам немного больше гибкости, чем Map / Reduce, но будет работать только тогда, когда вам нужно количество элементов (что вы делаете в вашем случае).

0 голосов
/ 30 января 2019

У вас есть 2 варианта:

  1. Создать Карта / Сократить индекс и запросить его
  2. Использовать Фасетный (агрегированный) поиск для запроса

Чтобы сделать выбор между двумя, учтите, что

  • Специально выделенный индекс быстрее запрашивать, но он занимает некоторое место в хранилище и производительности для повторной индексации измененных записей (может быть важно, если вам нужна немедленная согласованность и ожидание нестарелых индексов).
  • Фасет проще использовать, когда у вас уже есть поля, охватываемые существующим индексом. Я полагаю, вы понимаете важность статических индексов и уже имеете некоторые.

Хотя использование индекса Map / Reduce является простым и уже охватывается ответом Даниэля, ниже приведен пример использования 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_ForList - это существующий индекс для коллекции Site, который включает в себя CityCode поле
  • Site_IndexModel - это сохраненная структура Site_ForList index
...