2015-06-26 5 views
1

Я разрабатываю приложение ASP.NET MVC с использованием RavenDB 3. У меня нет большого опыта работы с ворон.Запросы поискового вызова Raven определенным образом

В общем случае при выполнении запросов для отображения данных на странице возвращаются первые 128 элементов. Дополнительные записи добавляются в «бесконечном прокрутке» -манере, используя запрограммированные запросы.

Теперь, однако, у меня есть требование, чтобы элементы загружались в «группы».

Предположим следующий класс:

public class Item { 
    public string Id { get; set; } 
    public int Group { get; set; } 
    public string text { get; set; } 
} 

Предположим, база данных содержит 40 элементов, имеющих группу = '1', 40 элементов, имеющих группу = '2' и 50 элементов, имеющих группу = '3'.

Это 130 предметов. Это означало бы, что последняя «группа» не будет полной. Это будет отсутствовать 2 предмета.

Мне нужен механизм, который знает об этом, так что он будет извлекать как минимум 128 И будет извлекать «лишние», если последняя группа не будет полностью включена.

Впоследствии, когда я прихожу на следующую страницу, я бы хотел, чтобы она начиналась со следующей группы.

Есть ли способ, которым я могу сделать эту работу без «изготовления» одной страницы, выполнив несколько вызовов?

EDIT: Я не могу предположить, что группы совершенно одинаковы по размеру, но я могу предположить, что размеры будут «Двойники»

Кроме того, я не могу изменить дизайн, чтобы сохранить все элементы в одном «group'- объект, например.

+0

Являются ли группы действительно числовыми? Если они загружаются в порядке? Например, ваш пейджинг всегда загружает группы 1-3, а на следующей странице - группы 4-6? –

+0

@KentCooper: да, они заказаны. – Bjorn

ответ

0

Итак, в основном вам нужно будет рассчитать количество результатов, которые были на предыдущих страницах, и количество результатов, которые находятся на текущей странице. Ниже приведено краткое примерное приложение, чтобы дать вам представление о том, как это сделать. Одно предупреждение, если количество результатов для диапазона текущей группы превышает MaxNumberOfRequestsPerSession, чем ошибка будет выбрана, так что вы можете захотеть поместить туда некоторую обработку.

Примечание для выполнения этого примера: Убедитесь, что платформа установлена ​​на x64 в визуальной студии, если вы используете самые последние версии RavenDB. В противном случае этот пример вызовет ошибку о том, что Ворон не будет стабильным в 32-битном режиме.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using Raven.Client; 
using Raven.Client.Embedded; 
using Raven.Client.Listeners; 

namespace ConsoleApplication 
{ 
    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      using (var gdm = new GroupDataManager()) 
      { 
       Console.WriteLine("Started Seeding"); 
       gdm.Seed().Wait(); 
       Console.WriteLine("Finished Seeding"); 
       Console.WriteLine("==============================================================="); 
       Console.WriteLine("Get First Page"); 
       Console.WriteLine("==============================================================="); 
       var firstPage = gdm.GetPagedGroupResults(1, 3).Result; 

       foreach (var item in firstPage) 
       { 
        Console.WriteLine(item.Text); 
       } 
       Console.WriteLine("==============================================================="); 
       Console.WriteLine("Get Second Page"); 
       Console.WriteLine("==============================================================="); 
       var secondPage = gdm.GetPagedGroupResults(2, 3).Result; 
       foreach (var item in secondPage) 
       { 
        Console.WriteLine(item.Text); 
       } 
      } 
      Console.ReadLine(); 
     } 
    } 

    public class GroupDataManager : IDisposable 
    { 
     private readonly IDocumentStore _documentStore = new EmbeddedRavenDatabase().Store; 

     public void Dispose() 
     { 
      _documentStore.Dispose(); 
     } 

     public async Task Seed() 
     { 
      var rnd = new Random(); 
      using (var session = _documentStore.OpenAsyncSession()) 
      { 
       for (var groupNumber = 1; groupNumber < 15; groupNumber++) 
       { 
        for (var i = 0; i < rnd.Next(5, 25); i++) 
        { 
         var item = new Item 
         { 
          Group = groupNumber, 
          Text = string.Format("Group: {0} Item:{1}", groupNumber, i) 
         }; 
         await session.StoreAsync(item); 
        } 
       } 

       await session.SaveChangesAsync(); 
      } 
     } 

     public async Task<IList<Item>> GetPagedGroupResults(int page, int numberOfGroupsPerPage) 
     { 
      var startingGroup = ((page - 1) * numberOfGroupsPerPage) + 1; 

      using (var session = _documentStore.OpenAsyncSession()) 
      { 
       // Calculate the number of items that were contained in the previous groups 
       var numberToSkip = await session.Query<Item>().CountAsync(item => item.Group < startingGroup); 

       var endGroup = startingGroup + numberOfGroupsPerPage; 

       // Calculate the number of items that are in the current range of groups 
       var numberToTake = await session.Query<Item>().CountAsync(item => item.Group >= startingGroup && item.Group < endGroup); 

       var results = await session.Query<Item>().Skip(numberToSkip).Take(numberToTake).ToListAsync(); 

       return results; 
      } 
     } 
    } 

    public class Item 
    { 
     public string Id { get; set; } 
     public int Group { get; set; } 
     public string Text { get; set; } 
    } 

    /// <summary> 
    /// For Testing Only. Prevents stale queries 
    /// </summary> 
    public class NoStaleQueriesAllowed : IDocumentQueryListener 
    { 
     public void BeforeQueryExecuted(IDocumentQueryCustomization queryCustomization) 
     { 
      queryCustomization.WaitForNonStaleResults(); 
     } 
    } 

    public class EmbeddedRavenDatabase 
    { 
     private static bool _configured = false; 

     private static readonly Lazy<IDocumentStore> _lazyDocStore = new Lazy<IDocumentStore>(() => 
     { 
      var docStore = new EmbeddableDocumentStore 
      { 
       RunInMemory = true 
      }; 

      docStore.RegisterListener(new NoStaleQueriesAllowed()); 
      docStore.Initialize(); 

      return docStore; 
     }); 

     public IDocumentStore Store 
     { 
      get { return _lazyDocStore.Value; } 
     } 
    } 
} 
+0

Это выглядит великолепно! Я могу основать свое решение на этом. Большое спасибо! – Bjorn

+0

Спасибо, рад, что я могу помочь! –

Смежные вопросы