概述
在使用NEST查询Elasticsearch索引文档过程中,有时你可能不需要从一个搜索查询返回文档的所有字段。例如,当显示博客的最近文章时,你可能只需要从查询到的最近文章结果集中返回博客的标题。
在NEST中,有两种方法可以实现仅返回文档中的部分字段(即部分文档),它们分别为:存储字段(stored fields)和源筛选(source filtering)。这两种方式在实现上还是有比较大的差别的。
以下分别对这两种返回部分文档的方法进行介绍。
使用存储字段(Stored fields)
在索引文档时,默认情况下,Elasticsearch会将最初发送的JSON文档存储在一个名为_source
的特殊字段中。从搜索查询返回的文档将从Elasticsearch返回的_source
字段中具体化。
当然,我们也可以通过Elasticsearch映射的store
属性来设置实现只存储JSON文档的部分字段数据的目的。当然,你可以禁用_source
,这样源文档就不会被存储,选择只存储特定的字段。还有一种可能性是,_source
包含一个值很大的字段。例如:博客文章的主体。但通常只需要另一个字段,如:博客文章的标题。
在本例中,我们不想为了得到一个小字段(文章的标题)而花费Elasticsearch反序列化整个_source
的代价。
当以这种方式存储字段时,可以在搜索请求中使用.StoredFields
指定要返回的单个(或者多个)字段,示例代码如下:
var searchResponse = _client.Search<Project>(s => s
.StoredFields(sf => sf
.Fields(
f => f.Name,
f => f.StartedOn,
f => f.Branches
)
)
.Query(q => q
.MatchAll()
)
);
并且,你还可以在返回的响应中使用.Fields
来检索,示例代码如下:
foreach (var fieldValues in searchResponse.Fields)
{
var document = new
{
Name = fieldValues.ValueOf<Project, string>(p => p.Name),
StartedOn = fieldValues.Value<DateTime>(Infer.Field<Project>(p => p.StartedOn)),
Branches = fieldValues.Values<Project, string>(p => p.Branches.First())
};
}
源筛选(Source filtering)
使用源筛选,只能从搜索查询中返回文档的某些字段,示例代码如下:
var searchResponse = _client.Search<Project>(s => s
.Source(sf => sf
.Includes(i => i
.Fields(
f => f.Name,
f => f.StartedOn,
f => f.Branches
)
)
.Excludes(e => e
.Fields("num*")
)
)
.Query(q => q
.MatchAll()
)
);
其中:
Include方法来指定要返回的字段
Exclude方法来指定要排除(不返回)的字段
以上两个方法Include和Exclude均可以使用通配符
通过在请求中指定源筛选,.Documents
将只包含部分文档,这些文档是从指定的源字段中具体化的,如下:
var partialProjects = searchResponse.Documents;
如果你要完全排除_source
中包含的文档内容,则可以通过指定.Source(false)
来实现,示例代码如下:
searchResponse = _client.Search<Project>(s => s
.Source(false)
.Query(q => q
.MatchAll()
)
);
发表评论
登录用户才能发表评论, 请 登 录 或者 注册