#.net #elasticsearch #nest
#.net #elasticsearch #гнездо
Вопрос:
Я использую NEST для запроса индекса ElasticSearch с использованием вложенного запроса, и все работает, но меня смутило назначение одной строки кода в запросе. Прежде чем я пойду дальше, я предоставлю все объекты и сам запрос.
Вот объект, который сопоставляется с индексом "country"
.
[ElasticsearchType(Name = "country")]
public class CountrySearchDto : ISearchIndex {
public int Id {get; set;}
public string Name { get; set; }
public string IsoCode {get; set;}
public string CountryCode{get; set;}
[Nested]
public List<AreaSearchDto> Areas {get; set;}
}
}
Вот объект, который сопоставляется с индексом "area"
.
public class AreaSearchDto : ISearchIndex{
public int Id {get; set;}
public string Name { get; set; }
public string GuideUrl { get; set; }
}
Как вы можете видеть, country
индекс areas
вложен в него. Сделанный мной запрос используется для поиска стран по областям, которые вложены внутри.
Вот запрос.
var searchResults = await _searchClient.SearchAsync<CountrySearchDto>(s => s
.Index("country")
.Query(q => q
.Nested(c => c
.Path(p => p.Areas)
.Query(nq => nq
.Term(t => t.Areas.FirstOrDefault().Name, searchTerm) // Where searchTerm is a string like "Sydney" or "London"
))
)
);
Я понимаю, как работает вложенный запрос, и он правильно получает всю необходимую мне информацию. Но что делает эта строка кода?
.Term(t => t.Areas.FirstOrDefault().Name, searchTerm) // Where searchTerm is a string like "Sydney" or "London"
Не FirstOrDefault()
ограничит ли запрос совпадением только по первому значению областей, а не по всем из них? Очевидно, что это не так, но мне интересно, может ли кто-нибудь объяснить, что здесь происходит.
Комментарии:
1. t.Areas — это массив областей, но вам нужно предоставить объект Areas в этом лямбда-выражении, поэтому он используется для доступа к объекту Areas.
Ответ №1:
t => t.Areas.FirstOrDefault().Name
это лямбда-выражение, которое преобразуется в имя поля для использования в запросе Elasticsearch. Он не выполняется сам по себе для извлечения значения первого имени области, а скорее выполняется для создания строки для имени поля, на которое нацелен запрос term. Как указывает Ахохштейн в комментариях, целью для запроса term внутри вложенного запроса является поле AreaSearchDto
в виде пути от корня документа, представленного CountrySearchDto
типом, к которому ограничен поисковый запрос. Использование лямбда-выражения для выполнения этого обхода позволяет использовать преимущества типов.
С searchTerm
помощью of "searchTerm"
сгенерированный запрос
POST http://localhost:9200/country/country/_search
{
"query": {
"nested": {
"path": "areas",
"query": {
"term": {
"areas.name": {
"value": "searchTerm"
}
}
}
}
}
}
Лямбда-выражение было вычислено до строки "areas.name"