我从Raven DB得到了一个奇怪的(非)结果。
我在客户端和服务器上运行最新的稳定版本v2.5.2666。
我想要检索的是“包含Id值为'x'的Component对象的第一个DeployProject文档。”
所以我尝试的第一件事就是:
var project = _documentSession.Query<DeployProject>()
.FirstOrDefault(i=>i.ComponentList.Any(j=>j.Id == componentId));
但即使我知道数据是正确的,它仍返回null。为了验证我没有疯狂,我在中间添加了一个.ToList(),因此它会将所有文件拉出到内存中查询它。
var project = _documentSession.Query<DeployProject>()
.ToList()
.FirstOrDefault(i=>i.ComponentList.Any(j=>j.Id == componentId));
而且DID有效,所以我的逻辑和数据是正确的。但当然它的效率非常低,整个想法是我只想拉出包含相关子记录的单个文档。
因此,Raven如何查询索引肯定存在问题,因为数据肯定存在,如果我将所有内容都拉入内存并运行相同的LINQ查询,我就可以检索它。
我的希望(恐惧?)指数是陈旧的,所以我告诉它给我新的数据:
var project = _documentSession.Query<DeployProject>()
.Customize(i=>i.WaitForNonStaleResultsAsOfLastWrite())
.FirstOrDefault(i=>i.ComponentList.Any(j=>j.Id == componentId));
但我又一次得到了。似乎Raven并没有按照我期望的方式处理LINQ语句,即LINQ to objects的工作方式。我知道可能存在一些差异,但这应该是一个非常简单的查询,我期望它可以工作。
有人有什么想法吗?我错过了一些简单的东西吗?
编辑:根据Raven的文档,看起来这应该没有任何冒险的索引:http://ravendb.net/docs/client-api/querying/using-linq-to-query-ravendb
除Where子句外,还有其他一些有用的运算符 你可以用来过滤结果。
任何可用于你的对象(或原始列表)的集合 实体只返回满足条件的人。 RavenDB也 支持In运算符,使反向任何比较更容易:
// Return only companies having at least one employee named "Ayende"
IQueryable<Company> companies = from c in session.Query<Company>()
where c.Employees.Any(employee => employee.Name == "Ayende")
select c;
答案 0 :(得分:0)
我认为这可能是一个类型问题,这很难看,但你试过这个吗?
var project = _documentSession.Query<DeployProject>()
.Where(i=>i.ComponentList.Any(j=>j.Id.ToString() == componentId.ToString()))
.FirstOrDefault();
如果这样可行,则原始查询将比较两种不同类型,而不是正确转换其中一种类型。
试试这个,看它能给你什么样的期待......
var project = _documentSession.Query<DeployProject>()
.Where(i=>i.ComponentList.Any(j=>j.Id == componentId))
.FirstOrDefault();
我知道它应该是相同的,但您可以使用调试器对此进行测试,以查看返回的内容:
var project = _documentSession.Query<DeployProject>()
.Where(i=>i.ComponentList.Any(j=>j.Id == componentId))
.ToList()
.FirstOrDefault();
答案 1 :(得分:0)
首先,subselect根本不是那么简单 - 从raven / LINQ的角度来看,这是一个非常复杂的查询。我会查看创建的任何ad-hoc索引,看看它是否确实有效。
这里更好的方法是建立索引。我遇到的两种方法是构建一个按componentId分组的索引,并列出部署项目。另一种方法是构建一个包含componentId的全文样式索引,然后你就可以非常有效地使用lucene的rails。