3

我从 Raven DB 得到了一个奇怪的(非)结果。

我正在客户端和服务器上运行最新的稳定版本 v2.5.2666。

我要检索的是“第一个包含 Id 值为'x'的组件对象的 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));

那确实有效,所以我的逻辑和数据是正确的。但是当然它确实效率很低,整个想法是我只想拉出包含相关子记录的单个文档。

因此,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-ravenb

除了 Where 子句,您还可以使用其他几个有用的运算符来过滤结果。

Any 可用于实体中的对象集合(或原始列表),以仅返回满足条件的对象。RavenDB 还支持 In 运算符,以使反向 Any 比较更容易:

// 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;
4

2 回答 2

1

我认为这可能是类型问题,这很难看,但是您尝试过吗?

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();
于 2013-08-19T18:41:17.627 回答
0

首先,子选择根本不是很简单——从 raven / LINQ 的角度来看,这是一个非常复杂的查询。我会查看创建的任何临时索引,看看它是否真的有效。

这里更好的方法是建立一个索引。让我印象深刻的两种方法是构建一个按 componentId 分组的索引,其中列出了部署项目。另一种方法是构建包含 componentId 的全文样式索引,然后您可以非常有效地使用 lucene 的导轨。

于 2013-08-19T19:16:25.463 回答