Search code examples
c#elasticsearchvisual-studio-2015nest

Unable to fetch nested key-val pairs dictionary from elastic client search response


I am trying, but failing to access the hits["_index"], hits["_type"], hits["_id"], hits["_score"] and hits["_source"] from the below mentioned dictionary to load into a db.

Trying to access every key-val pair below:

{
  "took" : 12,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },

  **"hits" : {
    "total" : 2700881,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "doc",
        "_id" : "R22224!!5333e7e4-9ee3-45f4-9dc3-2a8b8d8cdcf8",
        "_score" : 1.0,
        "_source" : {
          "duration" : 14986283,
          "group_id" : "com",
          "var_time" : "2018-04-24T17:05:13.082+02:00",
          "var_name" : "2",
        }
      }
    ]
  }**
}

Things I tried:

Tried the below c# code and reviewed following urls:

Unable to fetch _source dictionary key-val from elastic client search response https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/auto-map.html

public class HitsDocument
{

    [PropertyName("_index")]
    public string Hitsindex { get; set; }

    [PropertyName("_type")]
    public string Hitstype { get; set; }

    [PropertyName("_id")]
    public string Hitsid { get; set; }

    [PropertyName("_score")]
    public string Hitsscore { get; set; }

    [PropertyName("_source")]
    public RawDocument Hitssource { get; set; }

}

public class RawDocument
{

    [PropertyName("duration")]
    public long Duration { get; set; }

    [PropertyName("group_id")]
    public string GroupId { get; set; }

    [PropertyName("var_time")]
    public DateTime Vartime { get; set; }

    [PropertyName("var_name")]
    public string Varname { get; set; }

}

static void Main(string[] args)
{

    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));

    var settings = new ConnectionSettings(pool)
        .DefaultMappingFor<HitsDocument>(m => m
              .IndexName("test_index")
              .TypeName("doc"));

    var searchResponse = client.Search<HitsDocument>();

    var numberOfSlices = 4;


    var scrollAllObservable = client.ScrollAll<HitsDocument>("3m", numberOfSlices)
        .Wait(TimeSpan.FromMinutes(5), onNext: s =>
    {

        var docs = s.SearchResponse.DebugInformation;
        var documents = s.SearchResponse.Hits;

        foreach (var document in documents)
            {
                    // do something with this set of documents
                    // business logic to load into the database.

                MessageBox.Show("document.Id=" + document.Id);
                MessageBox.Show("document.Score=" + document.Score);
                MessageBox.Show("document.Source=" + document.Source);
                MessageBox.Show("document.Type=" + document.Type);
                MessageBox.Show("document.Index=" + document.Index);
        }
        });

}

What am I doing wrong and also please point me in direction of documentation that betters my understanding of the API client for nested dictionary?

Thanks in advance.

Update: The following code solution originally answered by @Russ Cam in this link answers it. I failed to realize it before.

public class RawDocument
{

    [PropertyName("duration")]
    public long Duration { get; set; }

    [PropertyName("group_id")]
    public string GroupId { get; set; }

    [PropertyName("var_time")]
    public DateTime Vartime { get; set; }

    [PropertyName("var_name")]
    public string Varname { get; set; }

}

static void Main(string[] args)
{

    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));

    var settings = new ConnectionSettings(pool)
        .DefaultMappingFor<RawDocument>(m => m
              .IndexName("test_index")
              .TypeName("doc"));

    var searchResponse = client.Search<RawDocument>();

    var numberOfSlices = 4;


    var scrollAllObservable = client.ScrollAll<RawDocument>("3m", numberOfSlices)
        .Wait(TimeSpan.FromMinutes(5), onNext: s =>
    {

        var docs = s.SearchResponse.DebugInformation;
        var documents = s.SearchResponse.Hits;

        foreach (var document in documents)
            {
                    // do something with this set of documents
                    // business logic to load into the database.

                MessageBox.Show("document.Id=" + document.Id);
                MessageBox.Show("document.Score=" + document.Score);
                MessageBox.Show("document.Source.duration=" + document.Source.duration);
                MessageBox.Show("document.Source.var_time=" + document.Source.var_time);
                MessageBox.Show("document.Source.var_name=" + document.Source.var_name);
                MessageBox.Show("document.Type=" + document.Type);
                MessageBox.Show("document.Index=" + document.Index);
        }
        });

}

Solution

  • As point by @Russ Cam, the below solution update is being posted as an answer for others to review.

    public class RawDocument
    {
    
        [PropertyName("duration")]
        public long Duration { get; set; }
    
        [PropertyName("group_id")]
        public string GroupId { get; set; }
    
        [PropertyName("var_time")]
        public DateTime Vartime { get; set; }
    
        [PropertyName("var_name")]
        public string Varname { get; set; }
    
    }
    
    static void Main(string[] args)
    {
    
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    
        var settings = new ConnectionSettings(pool)
            .DefaultMappingFor<RawDocument>(m => m
                  .IndexName("test_index")
                  .TypeName("doc"));
    
        var searchResponse = client.Search<RawDocument>();
    
        var numberOfSlices = 4;
    
    
        var scrollAllObservable = client.ScrollAll<RawDocument>("3m", numberOfSlices)
            .Wait(TimeSpan.FromMinutes(5), onNext: s =>
        {
    
            var docs = s.SearchResponse.DebugInformation;
            var documents = s.SearchResponse.Hits;
    
            foreach (var document in documents)
                {
                        // do something with this set of documents
                        // business logic to load into the database.
    
                    MessageBox.Show("document.Id=" + document.Id);
                    MessageBox.Show("document.Score=" + document.Score);
                    MessageBox.Show("document.Source.duration=" + document.Source.duration);
                    MessageBox.Show("document.Source.var_time=" + document.Source.var_time);
                    MessageBox.Show("document.Source.var_name=" + document.Source.var_name);
                    MessageBox.Show("document.Type=" + document.Type);
                    MessageBox.Show("document.Index=" + document.Index);
            }
            });
    
    }