2017-12-22 17 views
0

私はたくさんのgoogelingを行い、NESTとElasticSearchのドキュメンテーションをチェックしましたが、実際の例を見つけることはできませんでした/私の問題を解決しました。ElasticSearch NEST集約

私は例を挙げました。この例では、家族ごとの別々のLast_Namesの数と給与の合計を照会したいと考えています。

class Employee 
    { 
     public string First_Name { get; set; } 
     public string Last_Name { get; set; } 
     public int Salary { get; set; } 

     public Employee(string first_name, string last_name, int salary) 
     { 
      this.First_Name = first_name; 
      this.Last_Name = last_name; 
      this.Salary = salary; 
     } 
     public Employee() { } 
    } 
    private void button4_Click(object sender, EventArgs e) 
    { 
     // Create 4 employees 
     Employee al = new Employee("Al", "Bundy", 1500); 
     Employee bud = new Employee("Bud", "Bundy", 975); 
     Employee marcy = new Employee("Marcy", "Darcy", 4500); 
     Employee jefferson = new Employee("Jefferson", "Darcy", 0); 

     // add the 4 employees to the index 
     client.Index<Employee>(al); 
     client.Index<Employee>(bud); 
     client.Index<Employee>(marcy); 
     client.Index<Employee>(jefferson); 

     // query the index 
     var result = client.Search<Employee>(s => s 
      .Aggregations(a => a 
       .Terms("Families", ts => ts 
        .Field(o => o.Last_Name) 
        .Size(10) 
        .Aggregations(aa => aa 
         .Sum("FamilySalary", sa => sa 
          .Field(o => o.Salary) 
         ) 
        ) 
       ) 
      ) 
     ); 

     // Get the number of different families (Result should be 2: Bundy and Darcy) 
     // and get the family-salary of family Bundy and the family-salary for the Darcys 
     var names = result.Aggs.Terms("Families"); 
     // ?? var x = names.Sum("Bundy");   
    } 

私は、弾性から、以下の情報を必要とする:
*インデックス内の二つの異なる家族が
*家族バンディは2475
*家族ダーシーが助けてください4500

稼いで稼いである

答えて

2

ここに完全な例があります

private static void Main() 
{ 
    var defaultIndex = "employees"; 

    var settings = new ConnectionSettings(new Uri("http://localhost:9200")) 
     .InferMappingFor<Employee>(i => i 
      .IndexName(defaultIndex) 
     ) 
     .DefaultIndex(defaultIndex) 
     // following settings are useful while developing 
     // but probably don't want to use them in production 
     .DisableDirectStreaming() 
     .PrettyJson() 
     .OnRequestCompleted(callDetails => 
     { 
      if (callDetails.RequestBodyInBytes != null) 
      { 
       Console.WriteLine(
        $"{callDetails.HttpMethod} {callDetails.Uri} \n" + 
        $"{Encoding.UTF8.GetString(callDetails.RequestBodyInBytes)}"); 
      } 
      else 
      { 
       Console.WriteLine($"{callDetails.HttpMethod} {callDetails.Uri}"); 
      } 

      Console.WriteLine(); 

      if (callDetails.ResponseBodyInBytes != null) 
      { 
       Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" + 
         $"{Encoding.UTF8.GetString(callDetails.ResponseBodyInBytes)}\n" + 
         $"{new string('-', 30)}\n"); 
      } 
      else 
      { 
       Console.WriteLine($"Status: {callDetails.HttpStatusCode}\n" + 
         $"{new string('-', 30)}\n"); 
      } 
     }); 

    var client = new ElasticClient(settings); 

    if (client.IndexExists(defaultIndex).Exists) 
     client.DeleteIndex(defaultIndex); 

    client.CreateIndex(defaultIndex, c => c 
     .Settings(s => s 
      .NumberOfShards(1) 
     ) 
     .Mappings(m => m 
      .Map<Employee>(mm => mm 
       .AutoMap() 
      ) 
     ) 
    ); 

    // Create 4 employees 
    var al = new Employee("Al", "Bundy", 1500); 
    var bud = new Employee("Bud", "Bundy", 975); 
    var marcy = new Employee("Marcy", "Darcy", 4500); 
    var jefferson = new Employee("Jefferson", "Darcy", 0); 

    client.IndexMany(new [] { al, bud, marcy, jefferson }); 

    // refresh the index after indexing. We do this here for example purposes, 
    // but in a production system, it's preferable to use the refresh interval 
    // see https://www.elastic.co/blog/refreshing_news 
    client.Refresh(defaultIndex); 

    // query the index 
    var result = client.Search<Employee>(s => s 
     .Aggregations(a => a 
      .Terms("Families", ts => ts 
       .Field(o => o.Last_Name.Suffix("keyword")) // use the keyword sub-field for terms aggregation 
       .Size(10) 
       .Aggregations(aa => aa 
        .Sum("FamilySalary", sa => sa 
         .Field(o => o.Salary) 
        ) 
       ) 
      ) 
     ) 
    ); 

    // Get the number of different families (Result should be 2: Bundy and Darcy) 
    // and get the family-salary of family Bundy and the family-salary for the Darcys 
    var names = result.Aggs.Terms("Families"); 

    foreach(var name in names.Buckets) 
    { 
     var sum = name.Sum("FamilySalary"); 
     Console.WriteLine($"* family {name.Key} earns {sum.Value}"); 
    } 
} 

public class Employee 
{ 
    public string First_Name { get; set; } 
    public string Last_Name { get; set; } 
    public int Salary { get; set; } 

    public Employee(string first_name, string last_name, int salary) 
    { 
     this.First_Name = first_name; 
     this.Last_Name = last_name; 
     this.Salary = salary; 
    } 
    public Employee() { } 
} 

これは出力

  • 家族バンディが稼い2475
  • 家族ダーシーは4500

いくつかのポイントを稼いでいる:私は明示的にインデックスを作成しました

  1. automappingを使用する従業員のマッピング。この例は、索引や明示的なマッピングなしで機能しますが、わかりやすくするために追加して、コンソール出力で何が作成されているかを確認できます。従業員がニーズにどのようにマッピングされるかを変更することができます。
  2. すべてのドキュメントを一括でインデックスする
  3. 一括インデックス作成後にインデックスを更新します。本番システムでは、索引付け操作後にrefreshを呼び出さないのは、基礎となる逆索引にLuceneセグメントを書き込むためです。セグメントをマージするバックグラウンドプロセスがありますが、having many small segments can be a problem.リフレッシュインターバルを行うのが最善です。 Refreshは、文書を次の索引付けで検索できるようにするためにのみここで呼び出されます。
  4. アグリゲーションという用語は、stringプロパティをマッピングするときに、オートマッピングで作成されたkeyword sub fieldで実行する必要があります。キーワードフィールドのデータ型は、値)を索引付けし、集計およびソートに適した円柱データ構造のdoc値を利用します。
  5. 用語集にはバケットのコレクションが含まれています。ここで、各バケットキーは用語になります。各バケットはサブアグリゲーションを持つことができます。この場合は合計集計です。
関連する問題