Мы используем Raven для проверки логинов, чтобы люди могли попасть на наш сайт.
Мы обнаружили, что если вы сделаете это:
// Context is an IDocumentSession
Context.Query<UserModels>()
.SingleOrDefault(u => u.Email.ToLower() == email.ToLower());
Запрос фильтрует только первые 128 документов в Raven. В нашей базе данных их несколько тысяч, поэтому, если ваш адрес электронной почты не окажется среди первых 128 возвращенных, вам не повезло.
Ни один из примеров кода Raven или любой другой пример кода, с которым я сталкивался в сети, не выполняет никаких циклов с использованием Skip() и Take() для итерации по набору.
- Это желаемое поведение Рейвен?
- Это то же самое поведение, даже если вы используете расширенный запрос Lucene? т.е.; Ведут ли себя расширенные запросы по-другому?
- Подходит ли приведенное ниже решение? Выглядит немного некрасиво. :П
Мое решение состоит в том, чтобы перебирать набор всех документов до тех пор, пока я не столкнусь с ненулевым результатом, затем я прерываю и возвращаю .
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, и все работает так, как ожидалось.