我们正在使用 Raven 验证登录,以便人们可以进入我们的网站。
我们发现,如果你这样做:
// Context is an IDocumentSession
Context.Query<UserModels>()
.SingleOrDefault(u => u.Email.ToLower() == email.ToLower());
该查询仅过滤 Raven 中文档的前 128 个文档。我们的数据库中有几千个,所以除非您的电子邮件恰好在返回的前 128 个中,否则您就不走运了。
我在网上遇到的 Raven 示例代码或任何示例代码都没有使用 Skip() 和 Take() 执行任何循环来遍历集合。
- 这是 Raven 想要的行为吗?
- 即使您使用高级 Lucene 查询,行为是否相同?IE; 高级查询的行为有什么不同吗?
- 下面的解决方案合适吗?看起来有点丑。:P
我的解决方案是遍历所有文档的集合,直到遇到非空结果,然后我 break 并 return 。
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();
最后,我使用了 Advanced Lucene Syntax 而不是 linq 查询,并且一切都按预期工作。