RavenDB OrderByDescending и Take - неверные результаты - PullRequest
2 голосов
/ 19 января 2012

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

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

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();

В этой сетке должно быть еще несколько строк, время начала которых больше 19.01.2012 18:33:51 PM:

enter image description here

Редактировать: я удалил 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.

Ответы [ 2 ]

3 голосов
/ 29 января 2012

Наконец-то решена настоящая проблема.

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 элементам, которые вы возвращаете.Поэтому вы не видите, что товар упорядочен или отфильтрован должным образом.

Здесь немного больше информации здесь и здесь

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

1 голос
/ 20 января 2012

RavenDB использует конечную согласованность по умолчанию, поэтому индексы могут быть s , если вы явно не указали иначе .

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

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