您可以使用索引将每个 Bar 的副本存储在字段存储中,所以是的 - 它可以完成。但是您应该确保您了解这样做的影响。
通常,当您从 raven 查询时,索引仅用于确定哪些文档被发回。文档本身不是来自索引,而是来自文档存储。文档存储有 ACID 保证——这意味着无论索引的状态如何,您都将始终获得文档的最新副本。如果您从索引条目或索引字段存储中进行投影,那么您返回的值与索引本身一样陈旧。
假设您不断更新条形图,并且在索引赶上您上次更新之前进行搜索。您可以取回包含旧数据的 Bar。因此,您需要在结果中权衡数据的潜在陈旧性,可能使用其中一种WaitForNonStaleResultsAsOf...
自定义项 - 如果您有大量写入操作,这将减慢搜索结果的返回速度。
public class Foos_BarsByName
: AbstractIndexCreationTask<Foo, Foos_BarsByName.Result>
{
public class Result
{
public string Name { get; set; }
public Bar Bar { get; set; }
}
public Foos_BarsByName()
{
Map = foos => from foo in foos
from bar in foo.Bars
select new
{
bar.Name,
Bar = bar
};
Index(x => x.Name, FieldIndexing.Analyzed);
Index(x => x.Bar, FieldIndexing.No);
Store(x => x.Bar, FieldStorage.Yes);
}
}
var results = session.Query<Foos_BarsByName.Result, Foos_BarsByName>()
.Customize(x => x.WaitForNonStaleResultsAsOfNow())
.Search(x => x.Name, "roses")
.Select(x => x.Bar);
另一种处理方法可能是让所有 Foos 都回来,然后在客户端拉出您感兴趣的 Bars。至少,一切都来自文档存储:
public class Foos_BarsByName
: AbstractIndexCreationTask<Foo, Foos_BarsByName.Result>
{
public class Result
{
public string Name { get; set; }
}
public Foos_BarsByName()
{
Map = foos => from foo in foos
from bar in foo.Bars
select new
{
bar.Name
};
Index(x => x.Name, FieldIndexing.Analyzed);
}
}
var results = session.Query<Foos_BarsByName.Result, Foos_BarsByName>()
.Search(x => x.Name, "roses")
.As<Foo>()
.AsEnumerable()
.SelectMany(x => x.Bars)
.Where(x => x.Name.IndexOf("roses",
StringComparison.CurrentCultureIgnoreCase)
!= -1)
.AsEnumerable()
将强制执行 linq-to-raven 查询,使后面的一切都发生在客户端的 linq-to-objects 中。
当然,如果您正在执行比使用 c# 字符串函数表达的更高级的搜索,那么您将无法采用第二种方法。