Запрос Raven с помощью Where() фильтрует только первые 128 документов?

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

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

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

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

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

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

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

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;

}

РЕДАКТИРОВАТЬ:

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

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

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


person Jason Slocomb    schedule 24.02.2011    source источник


Ответы (1)


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

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

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

person Thomas Freudenberg    schedule 24.02.2011
comment
Я опубликовал это в группе Google, и Айенде упомянул, что они еще не поддерживают предикат в SingleOrDefault(). Моя проблема заключается в том, что запрос linq не передает параметр запроса на мой сервер. - person Jason Slocomb; 24.02.2011