Какую цель выполняет FirstOrDefault () во вложенном NEST-запросе Term ()? - PullRequest
0 голосов
/ 09 апреля 2019

Я использую 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 Ответ

1 голос
/ 10 апреля 2019

t => t.Areas.FirstOrDefault().Name - это лямбда-выражение, которое разрешается в имя поля для использования в запросе Elasticsearch. Не выполняется per se для извлечения значения имени первой области, а скорее обходится для создания строки для имени поля, на которое нацелен термин запроса. Как указывает aHochstein в комментариях, целью для термина запроса внутри вложенного запроса является поле AreaSearchDto в виде пути от корня документа, представленного типом CountrySearchDto, к которому относится поисковый запрос. Использование лямбда-выражения для выполнения этого обхода позволяет использовать преимущества типов.

При searchTerm из "searchTerm" сгенерированный запрос будет

POST http://localhost:9200/country/country/_search
{
  "query": {
    "nested": {
      "path": "areas",
      "query": {
        "term": {
          "areas.name": {
            "value": "searchTerm"
          }
        }
      }
    }
  }
}

Лямбда-выражение было оценено как строка "areas.name"

...