【c#】Elastic Searchに接続してデータを取得する方法

C#

Elasticsearchは様々なAPIを提供しており、c#のプログラムからAPIを介してElasticsearchを操作することもできます。

今回はc#からElasticsearchのデータを取得する方法を紹介します。

前提

バージョン

前提として、今回の.NETCoreとElasticsearchのバージョンは以下の通りです。

  • .NETCore:6.0
  • Elasticserch:7.10.2

パッケージ

c#からElasticsearchへの接続にはNestというパッケージを用います。Nestを導入していない方は、NugetでNestをインストールしてください。

コード

Elasticsearchへの接続

まずはElasticsearchに接続します。接続情報としてElasticsearchのURIを指定します。

using Nest;

namespace Elasticsearch 
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //接続
            var node = new Uri("http://localhost:9200");
            var settings = new ConnectionSettings(node);
            var client = new ElasticClient(settings);
        }
    }

Elasticsearchをクラスタ構成している場合、Uri()では複数のノードを指定することもできます。今回はシングルノードを想定して進めていきます。

ElasticClient()型の変数clientを元に様々な操作を実行していくことになります。

検索

インデックスを指定して、レコードの検索をやってみます。検索にはclient.Search()を用います。

var searchResponse = client.Search<dynamic>(s => s
                .Index("kibana_sample_data_ecommerce")
                .From(0)
                .Size(10)
                .MatchAll()
                
            );

上の例では、”kibana_sample_data_ecommerce”というインデックスに対して検索を行っています。対象レコードは先頭10件です。MatchAll()とすることで、特にフィルターのようなクエリは設けず、全レコードが対象になります。

これを実行したsearchResponseには、実行結果のオブジェクトが格納されます。このオブジェクトはレコード情報の他、様々な情報を保持しています。

レコードの値を取得するときはDocumentsを指定します。変数resultに検索結果だけを格納してみます。

var result = searchResponse.Documents;

デバッグで変数の中身を確認すると、10件分の結果が入っていることがわかります。

resultの中身

クエリを実行する

さらに細かくクエリを実行することもできます。ただし、上記のようなDynamic型ではフィールドの指定ができないので、フィールドを保持したクラスを作成したうえでクエリを作成する必要があります。

今回はインデックス”kibana_sample_data_ecommerce”のうち、email, user, currencyの3つのフィールドを持つクラスを作成します。

 public class EComerce
    {
        [Text(Name="email")]
        public string Email { get; set; }

        [Text(Name="user")]
        public string User { get; set; }

        [Text(Name="currency")]
        public string Currency { get; set; }
    }
}

このとき、各フィールドにはアトリビュートマッピング([ ]で囲まれた部分)が必要になります。これがないとエラーになるので、注意してください。詳細は以下リンクもご確認ください。

https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/attribute-mapping.html

では実際にクエリを記述した例を以下に示します。以下では、userフィールドが”diane”のレコードだけを検索取得します。client.Searchに続く型がEComerceになっている点に注意です。

var searchResponse = client.Search<EComerce>(s => s
                .Index("kibana_sample_data_ecommerce")
                .From(0)
                .Query(q => q
                    .Match(m => m
                        .Field(f => f.User)
                        .Query("diane")
                    )
                )
            );

var result = searchResponse.Documents;

このときの全コードをまとめて記載しておきます。

using Nest;

namespace Elasticsearch 
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //接続
            var node = new Uri("http://localhost:9200");
            var settings = new ConnectionSettings(node);
            var client = new ElasticClient(settings);

            var searchResponse = client.Search<EComerce>(s => s
                .Index("kibana_sample_data_ecommerce")
                .From(0)
                .Query(q => q
                    .Match(m => m
                        .Field(f => f.User)
                        .Query("diane")
                    )
                )
            );

            var result = searchResponse.Documents;
        }
    }


    public class EComerce
    {
        [Text(Name="email")]
        public string Email { get; set; }

        [Text(Name="user")]
        public string User { get; set; }

        [Text(Name="currency")]
        public string Currency { get; set; }
    }
}

まとめ

c#からElasticsearchに接続して検索する方法を紹介しました。

意外とこのあたりのドキュメントが乏しくて、データ取得するだけでも苦労した記憶がありますw

基本さえ押さえれば、後はクエリの書き方等共通的な部分になるので、頑張ってとりあえずデータとを取れるところまでこぎつけてください。この記事もその手助けになれば幸いです。

ではでは👋