NEST поддерживает это по умолчанию с концепцией, именуемой Безусловные запросы . Вы можете
private static void Main()
{
var defaultIndex = "documents";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool, new InMemoryConnection())
.DefaultIndex(defaultIndex)
.DisableDirectStreaming()
.PrettyJson()
.OnRequestCompleted(callDetails =>
{
if (callDetails.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{callDetails.HttpMethod} {callDetails.Uri} \n" +
$"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}");
}
Console.WriteLine();
if (callDetails.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
});
var client = new ElasticClient(settings);
var pageSize = 20;
var currentPageIndex = 0;
string search = "foo";
var searchResponse = client.Search<DocumentElasticModel>(s => s
.Size(pageSize)
.Skip(currentPageIndex * pageSize)
.Sort(ss => ss
.Descending(SortSpecialField.Score)
)
.Source(sf => sf
.Includes(i => i
.Fields(f => f.TopLevelMessage)
)
)
.Query(q => q
.Nested(c => c
.Name("named_query")
.Boost(1.1)
.InnerHits(i => i.Explain())
.Path(p => p.PerguntasRespostas)
.Query(nq => nq
.MultiMatch(m => m
.Fields(f => f
.Field(ff => ff.PerguntasRespostas.First().Message)
)
.Query(search)
)
)
.IgnoreUnmapped()
)
)
);
}
public class DocumentElasticModel
{
public string TopLevelMessage { get; set; }
public IEnumerable<PerguntasRespostas> PerguntasRespostas {get;set;}
}
public class PerguntasRespostas
{
public string Message { get; set; }
}
Это отправит следующий запрос
POST http://localhost:9200/documents/documentelasticmodel/_search
{
"from": 0,
"size": 20,
"sort": [
{
"_score": {
"order": "desc"
}
}
],
"_source": {
"includes": [
"topLevelMessage"
]
},
"query": {
"nested": {
"_name": "named_query",
"boost": 1.1,
"query": {
"multi_match": {
"query": "foo",
"fields": [
"perguntasRespostas.message"
]
}
},
"path": "perguntasRespostas",
"inner_hits": {
"explain": true
},
"ignore_unmapped": true
}
}
}
Теперь, если вы измените search
на string.Empty
или null
, вы получите
POST http://localhost:9200/documents/documentelasticmodel/_search
{
"from": 0,
"size": 20,
"sort": [
{
"_score": {
"order": "desc"
}
}
],
"_source": {
"includes": [
"topLevelMessage"
]
}
}
Без явного "query"
в запросе, это то же самое, что и запрос match_all
.
Если вы хотите переопределить функцию безусловного запроса в NEST, вы можете пометить запрос как .Verbatim()
, и NEST отправит точно так же, как
var searchResponse = client.Search<DocumentElasticModel>(s => s
.Size(pageSize)
.Skip(currentPageIndex * pageSize)
.Sort(ss => ss
.Descending(SortSpecialField.Score)
)
.Source(sf => sf
.Includes(i => i
.Fields(f => f.TopLevelMessage)
)
)
.Query(q => q
.Nested(c => c
.Verbatim() // <-- mark the nested query
.Name("named_query")
.Boost(1.1)
.InnerHits(i => i.Explain())
.Path(p => p.PerguntasRespostas)
.Query(nq => nq
.MultiMatch(m => m
.Verbatim() // <-- mark the inner query
.Fields(f => f
.Field(ff => ff.PerguntasRespostas.First().Message)
)
.Query(search)
)
)
.IgnoreUnmapped()
)
)
);
который отправляет
POST http://localhost:9200/documents/documentelasticmodel/_search
{
"from": 0,
"size": 20,
"sort": [
{
"_score": {
"order": "desc"
}
}
],
"_source": {
"includes": [
"topLevelMessage"
]
},
"query": {
"nested": {
"_name": "named_query",
"boost": 1.1,
"query": {
"multi_match": {
"fields": [
"perguntasRespostas.message"
]
}
},
"path": "perguntasRespostas",
"inner_hits": {
"explain": true
},
"ignore_unmapped": true
}
}
}
Вам нужно проверить, является ли этот запрос допустимым для Elasticsearch.