c# - NEST 会在 elasticsearch 中还是在客户端中进行项目?
问题描述
如果我有一个在elasticsearch中索引的复杂文档并使用DTO查询它,在将数据发送到C#客户端之前,是否会在elasticsearch中应用DTO所需字段的投影,或者发送完整的源代码,而C#将用它来水合DTO?
var response = await elasticClient.SearchAsync<TDto>(searchRequest);
基本上,我需要知道我是否可以简单地要求 aTDto
而不必担心ComplexDocument
被索引的较大数据量,或者我是否必须在 中指定Source
包含/排除searchRequest
以获得最佳性能。
解决方案
默认情况下,Elasticsearch 将发送回_source
每个搜索命中的完整文档。您可以使用源过滤_source
指定要包含/排除的字段
var client = new ElasticClient();
var searchResponse = client.Search<ComplexDocument>(s => s
.Source(sf => sf
.Includes(i => i
.Field(f => f.Path)
.Field(f => f.Content)
)
.ExcludeAll()
)
);
foreach(var source in searchResponse.Documents)
{
var path = source.Path;
}
发送
{
"_source": {
"excludes": ["*"],
"includes": ["path", "content"]
}
}
_source
或者你可以要求根本不回来
var searchResponse = client.Search<ComplexDocument>(s => s
.Source(false)
);
_source
使用源过滤,在 Elasticsearch 端完全读取存储字段,并应用过滤。这通常很好,但如果_source
是一个巨大的文档,并且您只想返回一个字段子集来响应搜索,您可能会决定使用存储字段。
顾名思义,存储字段是单独存储的字段_source
(通过store:true
在其映射中指定)并且可以在搜索响应中返回
var searchResponse = client.Search<ComplexDocument>(s => s
.StoredFields(f => f
.Field(ff => ff.Path)
)
);
foreach(var fields in searchResponse.Fields)
{
var path = fields.ValueOf<ComplexDocument, string>(f => f.Path);
}
"fields"
每次点击时,都会在一个属性中返回存储的字段。
如果我有一个在elasticsearch中索引的复杂文档并使用DTO查询它,在将数据发送到C#客户端之前,是否会在elasticsearch中应用DTO所需字段的投影,或者发送完整的源代码,而C#将用它来水合DTO?
总之,Elasticsearch 将返回完整的_source
,NEST 会将匹配的属性映射_source
到 DTO 的属性。默认情况下, NEST将 JSON 中的驼峰式属性映射到 POCO 属性。如果您想通过网络传输更少,请查看源过滤。您可能会封装该功能以在请求中仅包含 DTO 中的字段作为扩展方法SearchDescriptor<TInferDocument>
public class ComplexDocument
{
public int Id { get; set; }
public string Path { get; set; }
public string Content { get; set; }
public Attachment Attachment { get; set; }
}
public class SimpleDTO
{
public string Path { get; set; }
}
public static class SearchDescriptorExtensions
{
public static SearchDescriptor<TInferDocument> SourceIncludesDto<TInferDocument, TDocument>(this SearchDescriptor<TInferDocument> descriptor)
where TInferDocument : class
where TDocument : class
{
// TODO: cache this :)
Fields fields = typeof(TDocument).GetProperties();
return descriptor.Source(s => s
.Includes(f => f
.Fields(fields)
)
);
}
}
ISearchResponse<SimpleDTO> searchResponse =
client.Search<ComplexDocument, SimpleDTO>(s => s
.SourceIncludesDto<ComplexDocument, SimpleDTO>()
);
发送
{
"_source": {
"includes": ["path"]
}
}
推荐阅读
- python - 在python中查找正则表达式
- r - 如何从 r 中的单个数据帧中拆分具有随机子集的数据帧?
- javascript - Javascript:如何创建一个既像对象又像函数的变量?
- pandas - 大熊猫中用于方差分析和回归的分类变量?
- azure - Azure Kubernetes 服务:即使在 CD 管道中添加了 ImagePullSecret,图像提取错误(身份验证)
- laravel - 如何防止用户在浏览器中直接访问路由(后端控制器)?
- python - 使用 pip 在共享主机服务器上安装 mysqlclient 失败
- prolog - prolog 文本处理和构造状态的模板
- javascript - 无法从公共文件夹中获取一组 svg 文件到 React js 中的组件
- sql-loader - 为每个文件生成不同的序列号