NEST - 返回部分文档

Selecting fields to return

Version:5.xhtml

英文原文地址:Selecting fields to returnc#

有时候,不须要让 Elasticsearch 返回查询的文档中的所有字段。举个栗子,当展现最近发布的博客时,在查找到最新的帖子后只须要返回博客的标题。api

有两种方法能够用来返回文档中的部分字段,即部分文档(咱们使用这个术语来描述)。一个是 stored fields ,另外一个是 source filtering ,二者在工做方式上有很大的不一样。elasticsearch

Stored fields

索引文档时,默认状况下,Elasticsearch 将最初发送的 JSON 文档存储在一个名叫 _source 的特殊字段中。从搜索查询返回的文档是 Elasticsearch 返回的每一个命中的 _source 字段的具体化。ide

还能够在映射的时候使用 store ,把 JSON 文档中的字段分别存储在 Elasticsearch 中。为何要这么作呢?你可能禁用了 _source 以便不存储源文档,并选择存储特定的字段。另外一种可能性是,_source 包含一个具备较大值的字段(例如一篇博客的正文),但一般只须要另外一个字段(例如博客的标题)。这种状况下,咱们不想为了获得一个小字段而反序列化整个 _sourceui

重要:选择禁用类型映射中的 _source ,意味着不存储发送到 Elasticsearch 的原始 JSON 文档,所以永远没法检索原始文档。虽然这样作能够节省磁盘空间,但与此同时某些功能(如 Reindex API 或者 highlighting)也将没法正常工做。code

必定要认真考虑,禁用源文档是否真的符合你的需求。htm

以这种方式存储字段时,可使用搜索请求的 .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 中返回选择的字段。这即是 source filtering 的由来。

Source filtering

搜索查询时使用 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()
    )
);

在请求中指定了源过滤以后,响应对象的 .Documents 就只包含部分文档了、

var partialProjects = searchResponse.Documents;

你也能够从查询中彻底排除 _source

searchResponse = client.Search<Project>(s => s
    .Source(false)
    .Query(q => q
        .MatchAll()
    )
);
相关文章
相关标签/搜索