NEST项目会在elasticsearch还是在客户端?
Will NEST project in elasticsearch or in the client?
如果我在 elasticsearch 中索引了一个复杂的文档并使用 DTO 对其进行查询,在将数据发送到 C# 客户端之前,是否将 DTO 所需字段的投影应用到 elasticsearch 中,或者完整的源是已发送,C# 将使用它来补充 DTO?
var response = await elasticClient.SearchAsync<TDto>(searchRequest);
基本上,我需要知道我是否可以简单地请求一个 TDto
而不必担心索引的较大 ComplexDocument
的数据量,或者我是否必须指定 Source
inclusion/exclusion 在 searchRequest
中获得最佳性能。
默认情况下,Elasticsearch 会为每次搜索命中发回完整的 _source
文档。可以用source filtering
指定_source
到include/exclude的哪些字段
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"]
}
}
或者你可以要求根本不 return _source
var searchResponse = client.Search<ComplexDocument>(s => s
.Source(false)
);
使用源过滤,_source
的存储字段在 Elasticsearch 端被完全读取,并应用过滤。这通常很好,但是如果 _source
是一个 巨大的 文档,并且您只想 return 字段的子集来响应搜索,您可能决定改用 stored fields。
顾名思义,存储字段是单独存储到 _source
的字段(通过在其映射中指定 store:true
)并且可以在搜索响应中 returned
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);
}
存储的字段在每次点击时 return 编辑在 "fields"
属性 中。
If I have a complex document indexed in elasticsearch and query it
using a DTO, will a projection for the fields required by the DTO be
applied in elasticsearch, before sending the data to the C# client or
will the full source be sent, and C# will use that to hydrate the DTO?
总而言之,Elasticsearch 将 return 完整 _source
,NEST 会将 _source
中的匹配属性映射到 DTO 的属性。巢 maps camel case properties in JSON to the POCO properties by default。如果您想通过线路传输更少的数据,请查看源过滤。您可能会将功能打包为仅在请求中包含 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"]
}
}
如果我在 elasticsearch 中索引了一个复杂的文档并使用 DTO 对其进行查询,在将数据发送到 C# 客户端之前,是否将 DTO 所需字段的投影应用到 elasticsearch 中,或者完整的源是已发送,C# 将使用它来补充 DTO?
var response = await elasticClient.SearchAsync<TDto>(searchRequest);
基本上,我需要知道我是否可以简单地请求一个 TDto
而不必担心索引的较大 ComplexDocument
的数据量,或者我是否必须指定 Source
inclusion/exclusion 在 searchRequest
中获得最佳性能。
默认情况下,Elasticsearch 会为每次搜索命中发回完整的 _source
文档。可以用source filtering
_source
到include/exclude的哪些字段
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"]
}
}
或者你可以要求根本不 return _source
var searchResponse = client.Search<ComplexDocument>(s => s
.Source(false)
);
使用源过滤,_source
的存储字段在 Elasticsearch 端被完全读取,并应用过滤。这通常很好,但是如果 _source
是一个 巨大的 文档,并且您只想 return 字段的子集来响应搜索,您可能决定改用 stored fields。
顾名思义,存储字段是单独存储到 _source
的字段(通过在其映射中指定 store:true
)并且可以在搜索响应中 returned
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);
}
存储的字段在每次点击时 return 编辑在 "fields"
属性 中。
If I have a complex document indexed in elasticsearch and query it using a DTO, will a projection for the fields required by the DTO be applied in elasticsearch, before sending the data to the C# client or will the full source be sent, and C# will use that to hydrate the DTO?
总而言之,Elasticsearch 将 return 完整 _source
,NEST 会将 _source
中的匹配属性映射到 DTO 的属性。巢 maps camel case properties in JSON to the POCO properties by default。如果您想通过线路传输更少的数据,请查看源过滤。您可能会将功能打包为仅在请求中包含 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"]
}
}