Elasticsearch.Nest 教程系列 7-3 搜索:Selecting fields to return | 选择需要返回的字段

  • 本系列博文是“伪”官方文档翻译(更加本土化),并非完全将官方文档进行翻译,而是在查阅、测试原始文档并转换为自己真知灼见后的“准”翻译。有不同见解 / 说明不周的地方,还请海涵、不吝拍砖 :)

  • 官方文档见此:https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/introduction.html

  • 本系列对应的版本环境:ElasticSearch@7.3.1,NEST@7.3.1,IDE 和开发平台默认为 VS2019,.NET CORE 2.1


有的时候你不需要文档中的所有字段进行返回,有 2 种方法可以让你只返回文档中的某些字段。

通过 Stored Fields

索引文档时,默认情况下,Elasticsearch 会将最初发送的 JSON 文档存储在名为 _source 的特殊字段中。对于每个匹配,搜索查询返回的文档都是从 Elasticsearch 返回的 _source 字段中解析的。

注意: 禁用 _source 意味着不存储原始 JSON 文档,虽然可以节约磁盘,但会导致某些功能无法使用,如无法被检索,无法使用 Reindex API 和高亮。因此禁用 _source 需要根据你的应用场景谨慎考虑。

在搜索请求是通过 .StoredFields 指定要返回的字段值:

1
2
3
4
5
6
7
8
9
10
11
12
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 进行检索

1
2
3
4
5
6
7
8
9
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

通过 Source filtering 可以仅返回 _source中的一部分字段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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()
)
);

在请求中指定了 Source filtering 之后,.Documents 现在将仅包含部分文档

1
var partialProjects = searchResponse.Documents;

可以将 _source 从查询中完全排除在外

1
2
3
4
5
6
searchResponse = _client.Search<Project>(s => s
.Source(false)
.Query(q => q
.MatchAll()
)
);