По умолчанию 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"
при каждом попадании.
Если у меня есть сложный документ, проиндексированный вasticsearch, и запросить его с помощью DTO, будет ли применяться проекция для полей, требуемых DTO, в asticsearch, перед отправкой данных клиенту C# или будет отправлен полный источник, и 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"]
}
}