2016-11-11 26 views
0

我有存儲在ElasticSearch中的日誌和使用C#和Nest的Windows應用程序,該應用程序正在對ElasticSearch執行搜索。在ElasticSearch的映射如下所示:需要從ElasticSearch返回不同的字段,而不使用C#和嵌套的完整搜索結果文檔

"mappings": { 
    "qns": { 
     "properties": { 
      "@timestamp": { 
       "format": "strict_date_optional_time||epoch_millis", 
       "type": "date" 
      }, 
      "Error_Description": { 
       "index": "not_analyzed", 
       "type": "string" 
      }, 
      "Thread_Id": { 
       "index": "not_analyzed", 
       "type": "string" 
      }, 
      "Error_Description_Analyzed": { 
       "type": "string" 
      }, 
      "Error_Source": { 
       "index": "not_analyzed", 
       "type": "string" 
      }, 
      "record": { 
       "type": "string" 
      }, 
      "@version": { 
       "type": "string" 
      }, 
      "Log_Level": { 
       "type": "string" 
      }, 
      "Record": { 
       "type": "string" 
      }, 
      "id": { 
       "type": "long" 
      }, 
      "Error_Source_Analyzed": { 
       "type": "string" 
      }, 
      "Timestamp": { 
       "format": "strict_date_optional_time||epoch_millis", 
       "type": "date" 
      } 
     } 
    } 
} 

的相應的C#類如下:

[ElasticsearchType(IdProperty = "Id", Name = "qns")] 
public class QNS 
{ 
    [Number(NumberType.Long, Name = "id")] 
    public long Id { get; set; } 

    [Date(Name = "Timestamp")] 
    public DateTime Timestamp { get; set; } 

    [String(Name = "Error_Description", Index = FieldIndexOption.NotAnalyzed)] 
    public string ErrorDescriptionKeyword { get; set; } 

    [String(Name = "Error_Description_Analyzed")] 
    public string ErrorDescriptionAnalyzed { get; set; } 

    [String(Name = "Error_Source", Index = FieldIndexOption.NotAnalyzed)] 
    public string ErrorSourceKeyword { get; set; } 

    [String(Name = "Error_Source_Analyzed")] 
    public string ErrorSourceAnalyzed { get; set; } 

    [String(Name = "Thread_Id", Index = FieldIndexOption.NotAnalyzed)] 
    public string ThreadId { get; set; } 

    [String(Name = "Log_Level")] 
    public string LogLevel { get; set; } 

    [String(Index = FieldIndexOption.NotAnalyzed)] 
    public string Record { get; set; } 
} 

我需要一種方法來搜索不同的錯誤記錄中的日期時間範圍內的下降而相匹配的一定模式的範圍。雖然我能夠得到的結果,但我也讓所有滿足搜索,而我只需要在不同的錯誤字符串的文件。對於DISTINCT查詢我使用FluentNest(https://github.com/hoonzis/fluentnest)。 檢索結果的代碼如下:

private List<string> FindDistinctErrorsByPatternAndTimeRangeInternal(DateTime fromDateTime, DateTime toDateTime, List<pattern> patterns, string indexName, string type) 
    { 
     var documents = new List<QNS>(); 

     var fromTime = fromDateTime.ToString(Constants.IndexSearch.ES_DATETIME_FORMAT); 
     var toTime = toDateTime.ToString(Constants.IndexSearch.ES_DATETIME_FORMAT); 

     var patternQueries = new List<QueryContainer>(); 

     foreach (var p in patterns) 
     { 
      var pType = PatternType.unknown; 
      if (Enum.TryParse<PatternType>(p.Pattern_Type.ToLowerInvariant(), out pType)) 
      { 
       switch (pType) 
       { 
        case PatternType.word: 
         patternQueries.Add(Query<QNS>.Regexp(r => 
          r.Field(f => 
           f.ErrorDescriptionAnalyzed) 
           .Value(p.Pattern_Description) 
          ) 
         ); 
         break; 
        case PatternType.phrase: 
         patternQueries.Add(Query<QNS>.MatchPhrase(m => 
          m.Field(f => 
           f.ErrorDescriptionAnalyzed) 
           .Query(p.Pattern_Description) 
          ) 
         ); 
         break; 
        case PatternType.unknown: 
        default: 
         break; 
       } 
      } 
     } 

     var datetimeQuery = Query<QNS>.QueryString(q => 
           q.DefaultField(f => 
            f.Timestamp).Query($"[{fromTime} TO {toTime}]") 
           ); 

     var searchResults = client.Search<QNS>(s => s.Index(indexName) 
      .Type(type) 
      .Query(q => 
       q.Filtered(f => 
        f.Filter(fq => 
         fq.Bool(b => 
          b.MinimumShouldMatch(1).Should(patternQueries.ToArray()) 
         ) 
        ) 
        .Query(qd => 
         qd.Bool(b => 
          b.Must(datetimeQuery) 
         ) 
        ) 
       ) 
      ) 
      .Sort(sort => sort.Ascending(SortSpecialField.DocumentIndexOrder)) 
      .Aggregations(agg => agg.DistinctBy(q => q.ErrorDescriptionKeyword))); 

     var results = searchResults.Aggs.AsContainer<QNS>().GetDistinct(d => d.ErrorDescriptionKeyword); 

     return results.ToList(); 
    } 

我需要修改這個代碼僅返回不同的錯誤字符串,而不是整個結果集。來自查詢的命中數大約爲3500,並且僅存在2個不同的錯誤字符串。因此,我不打算使用它來獲取所有這些記錄是沒有意義的。有人可以幫助我使用日期範圍和模式正則表達式/短語匹配進行正確的聚合查詢,只使用Nest或Nest/FluentNest返回不同的錯誤記錄。

回答

0

我認爲你正在尋找terms聚集。

但是你整個查詢是有點怪。你有一些遺留要求嗎?

第一件事你有兩個字段ErrorDescriptionAnalyzed和ErrorDescriptionKeyword是你做一個不同的領域只是爲了有一個分析,而不是一個?爲什麼你不使用multi-fields

第二個過濾方法已經過時了一段時間。

這裏是一個快速的樣品,我希望能幫助

ElasticClient db = new ElasticClient(uri); 

      db.DeleteIndex(indexName); 

      var mappings = new CreateIndexDescriptor(indexName).Mappings(ms => ms.Map<A>(map => map. 
       AutoMap(). 
       Properties(props => 
        props.String(p => 
         p.Name(a => a.Text). 
         Fields(fields => 
          fields.String(pr => pr.Name("raw").NotAnalyzed())))))); 

      db.CreateIndex(mappings); 

      foreach (var item in Enumerable.Range(0, 10).Select(i => new A 
      { 
       Price1 = random.NextDouble() * 1000, 
       Date = i % 3 == 0 ? new DateTime(1900, 1, 1) : DateTime.Now, 
       Text = i % 2 == 0 ? "ABC" : "EFG" 
      })) 
      { 
       db.Index(item, inx => inx.Index(indexName)); 
      } 

      var toDate = DateTime.Now + TimeSpan.FromDays(1); 
      var fromDate = DateTime.Now - TimeSpan.FromDays(30); 

      var data = db.Search<A>(s => 
       s.Index(indexName) 
       .Query(q=> 
         q.DateRange(r => r.Field(f => f.Date).GreaterThan(fromDate).LessThanOrEquals(toDate)) 
         && 
         (
         //term query is for finding words by default all words are lowercase but you can set a different analyzer 
         q.Term(t => t.Field(f => f.Text).Value("ABC".ToLower())) 
         || 
//Raw field is not analysed so no need to lower case you can use you query here if you want 
         q.Term(t => t.Field("text.raw").Value("EFG")) 
         ) 
       ).Aggregations(aggr => aggr.Terms("distinct", aterm => aterm.Field("text.raw")))); 
相關問題