Estamos usando Raven para validar inicios de sesión para que las personas puedan ingresar a nuestro sitio.Consultar Raven con Where() solo filtros contra los primeros 128 documentos?
Lo que hemos encontrado es que si usted hace esto:
// Context is an IDocumentSession
Context.Query<UserModels>()
.SingleOrDefault(u => u.Email.ToLower() == email.ToLower());
La consulta sólo filtros en los primeros 128 documentos de los documentos en Raven. Hay miles en nuestra base de datos, así que a menos que su correo electrónico esté en los primeros 128 devueltos, no tiene suerte.
Ninguno del código de ejemplo de Raven o cualquier código de muestra que he encontrado en la red realiza cualquier bucle usando Omitir() y tomar() para recorrer el conjunto.
- ¿Es este el comportamiento deseado de Raven?
- ¿Es el mismo comportamiento incluso si utiliza una consulta avanzada de Lucene? es decir; ¿Las consultas avanzadas se comportan de forma diferente?
- ¿La solución a continuación es apropiada? Se ve un poco feo. : P
Mi solución es recorrer el conjunto de todos los documentos hasta que I encuentre un resultado no nulo, luego lo rompo y lo devuelvo.
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:
uso de la corrección a continuación no está pasando Parámetros de consulta a mi ejemplo RavenDB. Aún no estoy seguro de por qué.
Context.Query<UserModels>()
.Where(u => u.Email == email)
.SingleOrDefault();
Al final estoy usando la sintaxis de Lucene avanzada en lugar de las consultas de linq y todo está funcionando como se esperaba.
He publicado esto en el grupo de google y Ayende mencionó que aún no admiten un predicado en SingleOrDefault(). Mi problema es que la consulta de linq no pasa un parámetro de consulta a mi servidor. –