Запрос Raven с помощью Where () фильтрует только первые 128 документов? - PullRequest
7 голосов
/ 24 февраля 2011

Мы используем Raven для проверки логинов, чтобы люди могли зайти на наш сайт.

Мы обнаружили, что если вы сделаете это:

// Context is an IDocumentSession 
Context.Query<UserModels>()
           .SingleOrDefault(u => u.Email.ToLower() == email.ToLower()); 

Запрос фильтрует только первые 128 документов документов в Raven. В нашей базе данных есть несколько тысяч, так что если ваш электронная почта оказывается в первых 128 возвращенных, вам не повезло.

Ни один из образцов кода Raven или любой другой Пример кода, с которым я сталкивался в сети, выполняет любые циклы, используя Пропустить () и Take (), чтобы перебрать множество.

  1. Это желаемое поведение ворона?
  2. Это то же самое поведение, даже если вы используете расширенный Lucene Query? то есть; Поведенческие запросы ведут себя иначе?
  3. Подходит ли приведенное ниже решение? Выглядит немного некрасиво : P

Мое решение состоит в том, чтобы просмотреть все документы до тех пор, пока я сталкиваюсь с ненулевым результатом, затем я ломаюсь и возвращаюсь.

public T SingleWithIndex(string indexName, Func<T, bool> where)
{
    var pageIndex = 1;
    const int pageSize = 1024;
    RavenQueryStatistics stats;

var queryResults = Context.Query<T>(indexName)
    .Statistics(out stats)
    .Customize(x => x.WaitForNonStaleResults())
    .Take(pageSize)
    .Where(where).SingleOrDefault();

if (queryResults == null && stats.TotalResults > pageSize)
{
    for (var i = 0; i < (stats.TotalResults / (pageIndex * pageSize)); i++)
    {
        queryResults = Context.Query<T>(indexName)
            .Statistics(out stats)
            .Customize(x => x.WaitForNonStaleResults())
            .Skip(pageIndex * pageSize)
            .Take(pageSize)
            .Where(where).SingleOrDefault();

        if (queryResults != null) break;

        pageIndex++;
    }

}

return queryResults;

} * * тысяча двадцать-один

EDIT:

Использование исправления ниже не передает параметры запроса моему экземпляру RavenDB. Пока не знаю почему.

Context.Query<UserModels>()
    .Where(u => u.Email == email)
    .SingleOrDefault();

В конце я использую расширенный синтаксис Lucene вместо запросов linq, и все работает как положено.

1 Ответ

4 голосов
/ 24 февраля 2011

RavenDB не понимает SingleOrDefault, поэтому он выполняет запрос без фильтра. Затем ваше условие выполняется для набора результатов, но по умолчанию Raven возвращает только первые 128 документов. Вместо этого вы должны позвонить

Context.Query<UserModels>()
       .Where(u => u.Email == email)
       .SingleOrDefault();

поэтому фильтрация выполняется RavenDB / Lucene.

...