2012-01-19 10 views
2

Этот запрос работал для меня до недавнего времени. У меня теперь есть 135 инсталляционных документов в моем RavenDB. Вместо того, чтобы получать самое последнее по времени начала, это в основном, но последние пары, самые последние документы не отображаются из этого запроса. Я спрашиваю неправильно? Есть ли другой способ сделать OrderByDescending и Take with RavenDB, о котором я должен знать? Есть ли ограничение количества документов на то, что я могу запросить правильно?RavenDB OrderByDescending and Take - неверные результаты

Примечание: я отлаживал это, и запрос действительно возвращает то, что мы видим в сетке. Между временем выполнения запроса и показанным в пользовательском интерфейсе изменений нет.

IEnumerable<InstallationSummary> installationSummaries = 
    QueryAndCacheEtags(session => session.Advanced.LuceneQuery<InstallationSummary>() 
    .Include(x => x.ApplicationServerId) 
    .Include(x => x.ApplicationWithOverrideVariableGroup.ApplicationId) 
    .Include(x => x.ApplicationWithOverrideVariableGroup.CustomVariableGroupId) 
    .OrderByDescending(summary => summary.InstallationStart) 
    .Take(numberToRetrieve)).Cast<InstallationSummary>().ToList(); 

Эта сетка должна показать еще несколько строк в ней с запуском раза больше, чем 1/19/2012 6:33:51 PM:

enter image description here

Edit: я удалил Take (numberToRetrieve) из запроса, и я получаю только 128 из 160 документов InstallationSummary. Я вижу все 160 в RavenDB Studio, но только 128 возвращаются из запроса. 128 ... 128 ... сила 2 ... Я попал в какой-то предел?

Хорошо, это выглядит, как я попал в лимит 128: http://www.blogcoward.com/archive/2010/05/21/RavenDB-and-a-brief-design-philosophy-discussion-with-Ayende.aspx http://codeofrob.com/archive/2010/05/12/ravendb-basic-usage-considerations.aspx

Но почему? У меня есть метод Take(). Как я могу получить 50 самых последних документов?

Как немного взломать, нижеследующий запрос по крайней мере покажет самое последнее. Это не совсем то, что я хочу, потому что мне нужны последние 50, независимо от даты. Пока их не будет больше 50 с даты начала, это будет по крайней мере показывать самые последние предметы.

using Raven.Client.Linq; 

DateTime startDate = new DateTime(2012, 1, 18); 

IEnumerable<InstallationSummary> installationSummaries = 
QueryAndCacheEtags(session => session.Query<InstallationSummary>() 
.Include(x => x.ApplicationServerId) 
.Include(x => x.ApplicationWithOverrideVariableGroup.ApplicationId) 
.Include(x => x.ApplicationWithOverrideVariableGroup.CustomVariableGroupId)       
.Where(x => x.InstallationStart > startDate) 
.OrderByDescending(summary => summary.InstallationStart)       
.Take(numberToRetrieve) 
).Cast<InstallationSummary>().ToList(); 

Мне нужно было перейти от LuceneQuery к просто Query, и мне пришлось добавить предложение Where.

+0

В дополнение к этому, что такое QueryAndCacheEtags? Это кажется странным, тем более что RavenDB уже делает это для вас –

+0

QueryAndCacheEtags() выполняет запрос и сохраняет этики в кеше, когда объекты впоследствии сохраняются. Поскольку я не открываю сеанс для жизни приложения, и пользователь может сэкономить несколько часов после его получения, я сохраняю этиграммы для последующего использования. Это единственный способ, которым я знал, как это сделать. Я все еще изучаю Ворона. –

+0

Что такое подпись метода QueryAndCacheEtags() - это выражение > или просто Func <..>? –

ответ

3

Наконец разработана реальная проблема.

IEnumerable<InstallationSummary> installationSummaries = 
    QueryAndCacheEtags(session => session.Query<InstallationSummary>() 
     .Include(x => x.ApplicationServerId) 
     .Include(x => x.ApplicationWithOverrideVariableGroup.ApplicationId) 
     .Include(x => x.ApplicationWithOverrideVariableGroup.CustomVariableGroupId)       
     .Where(x => x.InstallationStart > startDate) 
     .OrderByDescending(summary => summary.InstallationStart)       
     .Take(numberToRetrieve)) 
     .Cast<InstallationSummary>() 
     .ToList(); 

Сигнатура QueryAndCacheEtags (..) функция Func<T>, не Expression<Func<T>>. И это возвращает IEnumerable<T> не IQueryable<T>

Это превращает заявление IQueryable<T> в IEnumerable<T> в этой точке. Это означает, что сервер RavenDB обрабатывает только первую часть запроса, у которой нет фильтрации или упорядочения.

Остальные утверждения, а затем применяются в памяти для 128 предметов, которые вы возвращаете. Следовательно, почему вы не видите товар заказанным или фильтрованным должным образом.

Там немного подробнее here и here

Как правило, вы не должны беспокоиться о разнице между Func<T> и Expression<Func<T>>, компилятор обрабатывает его для вас. Но если вы представите свой собственный вызов функции в оператор LINQ, вам нужно это сделать правильно.

+0

В качестве теста я изменил код на IEnumerable, и все кажется, что все еще работает. В консоли Raven я вижу pageSize = 50, поэтому я бы предположил, что Take() делает это на сервере Raven. Теперь я задаюсь вопросом, существует ли разница между session.Query и session.Advanced.LuceneQuery. Я пытаюсь заставить это не работать снова, чтобы увеличить мое понимание, но оно все еще работает. Хмм ... –

+0

Лучшая подсказка - использовать Intellisense и mouse-overs, чтобы Visual Studio рассказывала вам, какую версию функции вызывается. Сделайте это один из функций .Where (..) и .OrderBy (..). Также, глядя на консоль Raven, это хорошая идея (как вы уже делаете) –

+0

Да, даже при использовании IEnumerable, OrderByDescending() является IRavenQueryable, а Take() - IQueryable. Поэтому я предполагаю, что это не просто IEnumerable vs IQueryable. Похоже, мне нужен только IQueryable при использовании LuceneQuery. –

1

RavenDB по умолчанию использует конечную консистенцию, поэтому индексы могут быть равны tale unless you explicitly specify otherwise.

Добавьте строку ниже (или один из его вариантов) на запрос к этому:

.Customize(x => x.WaitForNonStaleResultsAsOfNow()) 
+0

Спасибо, Мэтт. Сегодня я должен уметь это попробовать. Я дам вам знать, если это сработает. –

+0

Ahh Matt - я думал, QueryAndCacheEtags был каким-то секретным передовым методом RavenDb. Не пользовательский: P (Потому что я думал о том же ответе, что и вы, сделал): P –

+0

Мэтт, это работает для LuceneQuery? Я не могу настроить Customize() для отображения в intellisense. –