2015-01-25 2 views
8

나는 둥지를 처음 사용하기 때문에 나는 내가 생각하는 것처럼 내 쿼리를 작성하지 않을 가능성이 높습니다. 나의 질문은 남자에게 물고기를주는 것보다 물고기를 가르치기위한 라인에 더 가깝다. 그러나, 나는 현재의 문제를 예제로 사용하겠습니다.Nest 쿼리는 어떻게 디버깅합니까?

ElasticSearch에 Series 유형의 여러 문서가 있습니다. 나는 쿼리 관련된 정보 만 가진 속성과 공공 수정없이 아래 그것을 스텁 것 :

class Series 
{ 
    string Id {get; set;} 
    DateTime StartDate {get; set;} 
    DateTime EndDate {get; set;} 
    HashSet<Role> ReleasableTo {get; set;} 
} 

이 모든 벌금과 멋쟁이입니다. 나는 할 수있다 Get()Series 문제 없음 객체. 내가 겪고있는 문제는 Nest가 내 쿼리를 어떻게 포맷하는지 파악하려고하는 것입니다. 나의 즉각적인 목표는 가장 최근의 SeriesRole.Visitor으로 해제하는 것입니다. 나는 둥지 같은 쿼리 설정 : 그것은 단지 ReleasableToRole.Visitor을 수있는 사람을 고려, 그래서 내 마음에

ISearchResponse<Series> response = client 
    .Search<Series>(r => 
     r.Filter(f => 
      f.Term<Role>(t=>t.ReleasableTo.First(), Role.Visitor)) 
    .SortDescending(ser => ser.EndDate).Size(1)); 

을,이 시리즈를 필터링하는 쿼리를 생성해야 최종 날짜 별 종류 및 한도를 반전 한 사람에게 결과가 돌아왔다. 그게 내가 원하는거야. 시리즈 중 수천 개의 레코드에서 약 90 %가이 프로파일에 적합합니다. 불행히도 쿼리는 0 개의 결과를 반환합니다. 오류가없고 결과가 없습니다. 내가 모르는 것은 Nest가 이해할 수없는 쿼리 구조를 생성하고 있거나 단순히 ElasticSearch를 충분히 알지 못한다면 API를 잘못 사용하는 것입니다. Filter 조항을 삭제하면 결과가 나오지만 모든 사람이 볼 수있는 것은 아닙니다.

Nest가 생성하고 ElasticSearch로 보내는 JSON을 보려면 어떻게해야합니까?

답변

12

당신은 아래로 검색 요청 URL 및 JSON 요청 본문의 값을 얻을 수 있습니다 :

var requestURL = response.RequestInformation.RequestUrl; 
var jsonBody = Encoding.UTF8.GetString(response.RequestInformation.Request); 

당신은 디버깅을 위해 RequestInformation에 유용한 속성을 찾을 수 있습니다.

+0

"검색어"를 입력하면 매우 유용합니다. { "releasableTo": "방문자"}) 나는 내가 원하는 것을 얻는다. 내 인덱스는 미세 조정이 필요하다고 생각합니다. –

1

EnableTrace 또는 ConnectionStatusHandler을 사용할 수 있습니다. 더 자세한 내용 here. 당신이에 대한 종속성이 없다, 그래서 당신의 ElasticClient 어떤 연결 속성을 필요로하지 않는다

var client = new ElasticClient(); 

var seriesSearch = new SearchDescriptor<Series>(); 
seriesSearch.Filter(f => f 
    .Term<Role>(t => t.ReleasableTo.First(), Role.Visitor)) 
    .SortDescending(ser => ser.EndDate) 
    .Size(1)); 

string searchJson = Encoding.UTF8.GetString(client.Serializer.Serialize(seriesSearch)); 

참고 :

6

내가 제안 bsarkar보다 한 단계 더 걸릴하고 모두 왕복에 대한 필요성을 제거하고자 ES 노드.

+3

NEST 2.4.5에서 Serialize 함수는 더 이상 문자열을 반환하지 않으며 매개 변수로 대상 스트림을 가져와야합니다. 예 : (var searchRequestStream = new MemoryStream()) 사용 { client.Serializer.Serialize (seriesSearch, searchRequestStream); var searchRequestString = Encoding.UTF8.GetString (searchRequestStream.GetBuffer()); } –

5

정말 쉽습니다. 이 코드를 검색하는 코드는 다음과 같습니다.

var results = client.Search<SearchItem>(s => s.AllIndices() 
    .Query(q => 
      q.Term(p => p.LastName, searchItem.LastName) 
      && q.Term(p => p.FirstName, searchItem.FirstName) 
      && q.Term(p => p.ApplicationCode, searchItem.ApplicationCode) 
      ) 
    .Size(1000) 
    ); 
var list = results.Documents.ToList(); 

위의 줄에 중단 점을 설정합니다. 그런 다음, Visual Studio를 직접 실행 창에,이 입력 :

?results.ConnectionStatus 

을 그리고 그것은 나를이 제공 :이 도움이

{StatusCode: 200, 
    Method: POST, 
    Url: http://localhost:9200/_all/searchitem/_search, 
    Request: { 
    "size": 1000, 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "term": { 
      "lastName": { 
       "value": "carr" 
      } 
      } 
     }, 
     { 
      "term": { 
      "firstName": { 
       "value": "adrian" 
      } 
      } 
     } 
     ] 
    } 
    } 
} 

희망을.

+1

이것은 정말 유용한 기술입니다. –

+0

내가 누락 된 항목이 확실하지 않지만 결과 개체에 ConnectionStatus 속성이 표시되지 않습니다. – Tjaart

7

NEST은 .NET API 바로크입니다. 2.1+ 호출 수준 :

IElasticClient client = new ElasticClient(); 
var searchDescriptor = new SearchDescriptor<Series>(); 
var query = Query<Series>.Term(...); 
var pretty = query.ToPrettyString(query); 
var json = client.ToRawRequest(searchDescriptor.Query(descriptor => query)); 

구성 수준에서 : 응답 수준에

var settings = new ConnectionSettings() 
        .PrettyJson().DisableDirectStreaming() 
        .OnRequestCompleted(details=> Debug.WriteLine(Encoding.UTF8.GetString(details.RequestBodyInBytes))); 

CallDetails.RequestBodyInBytes으로 보인다.

중고 확장 : 최신 탄성 검색 5+를 사용

/// <summary> 
    /// Converts search to raw JSON request for debugging. 
    /// </summary> 
    /// <typeparam name="T">The type.</typeparam> 
    /// <param name="self">The self.</param> 
    /// <param name="searchDescriptor">The search descriptor.</param> 
    /// <returns>The string.</returns> 
    public static string ToRawRequest<T>(this IElasticClient self, SearchDescriptor<T> searchDescriptor) where T : class 
    { 
     using (var output = new MemoryStream()) 
     { 
      self.Serializer.Serialize(searchDescriptor, output); 
      output.Position = 0; 
      var rawQuery = new StreamReader(output).ReadToEnd(); 
      return rawQuery; 
     } 
    } 

    /// <summary> 
    /// Prints query into string. 
    /// </summary> 
    /// <param name="self">The self.</param> 
    /// <returns>The value.</returns> 
    public static string ToPrettyString(this QueryContainer self) 
    { 
     using (var settings = new ConnectionSettings()) 
     { 
      var visitor = new DslPrettyPrintVisitor(settings); 
      self.Accept(visitor); 
      return visitor.PrettyPrint.Replace(Environment.NewLine, string.Empty); 
     }                   
    } 
4

, 나는 다음과 같이 광산 (아드리안 카의 방법 덕분에) 얻을 수있었습니다 : 준

var jsonOutput = System.Text.Encoding.UTF8.GetString(
    response.ApiCall.RequestBodyInBytes 
) 

의 나 출력 결과 :

관련 문제