Какую цель `FirstOrDefault ()` имеет во вложенном запросе `Term ()` вложенного ГНЕЗДА?

#.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"