使用Where()查询Raven只过滤前128个文档?

Jas*_*omb 7 lucene ravendb

我们正在使用Raven来验证登录,以便人们可以进入我们的网站.

我们发现如果你这样做:

// Context is an IDocumentSession 
Context.Query<UserModels>()
           .SingleOrDefault(u => u.Email.ToLower() == email.ToLower()); 
Run Code Online (Sandbox Code Playgroud)

该查询仅过滤Raven中文档的前128个文档.在我们的数据库中有几千个,所以除非你的电子邮件恰好在第一个128返回,否则你运气不好.

Raven示例代码或我在网上遇到的任何示例代码都没有使用Skip()和Take()迭代整个集合执行任何循环.

  1. 这是Raven的理想行为吗?
  2. 即使您使用高级Lucene查询,它是否也是相同的行为?即; 高级查询的行为有何不同?
  3. 下面的解决方案是否合适?看起来有点难看.:P

我的解决方案是循环遍历所有文档的集合,直到遇到非null结果,然后我中断并返回.

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;
Run Code Online (Sandbox Code Playgroud)

}

编辑:

使用下面的修复程序不会将查询参数传递给我的RavenDB实例.不知道为什么.

Context.Query<UserModels>()
    .Where(u => u.Email == email)
    .SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)

最后,我使用的是高级Lucene语法而不是linq查询,并且事情按预期工作.

Tho*_*erg 4

RavenDB 不理解SingleOrDefault,因此它在没有过滤器的情况下执行查询。然后在结果集上执行您的条件,但默认情况下 Raven 仅返回前 128 个文档。相反,你必须打电话

Context.Query<UserModels>()
       .Where(u => u.Email == email)
       .SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)

所以过滤是由RavenDB/Lucene完成的。