Returning multiple derived class instances from Elasticsearch using NEST and .NET

Viewed 1363

I'm trying to use NEST to return various objects derived from a common subclass.

In this example I have a base class called "Person" and then I have derived classes called "Firefighter" and "Teacher". Instances are stored in an index called "people".

I'd like to do a search on my index and return a mix of Firefighters and Teachers, but the best I can get back is a list of Persons.

The documentation calls for the use of ISearchResponse.Types, but I don't see that this function exists. This post, here on StackOverflow, also references the .Types function but I just don't see it as an option.

Here's an example of the problem I'm trying to solve.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Nest;
using Elasticsearch;
using Elasticsearch.Net;

namespace ElasticSearchTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var myTeacher = new Teacher { id="1", firstName = "Steve", lastName = "TheTeacher", gradeNumber = 8 };
            var myFiregighter = new Firefighter { id="2", firstName = "Frank", lastName = "TheFirefighter", helmetSize = 12 };

            SingleNodeConnectionPool esPool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
            ConnectionSettings esSettings = new ConnectionSettings(esPool);
            esSettings.DefaultIndex("people");
            Nest.ElasticClient esClient = new ElasticClient(esSettings);

            esClient.DeleteIndex("people");
            esClient.Index<Teacher>(myTeacher);
            esClient.Index<Firefighter>(myFiregighter);

            System.Threading.Thread.Sleep(2000);

            ISearchResponse<Person> response = esClient.Search<Person>(s => s   
                .AllTypes()
                .MatchAll()
                );

            foreach (Person person in response.Documents)
                Console.WriteLine(person);
        }

        public class Person
        {
            public string id { get; set; }
            public string firstName { get; set; }
            public string lastName { get; set; }
            public override string ToString() { return String.Format("{0}, {1}", lastName, firstName);}
        }
        public class Firefighter : Person
        {
            public int helmetSize { get; set; }
        }
        public class Teacher : Person {
            public int gradeNumber { get; set; } 
        }
    }
}

The data appears to be structured correctly inside Elasticsearch:

{
    took: 1,
    timed_out: false,
    _shards: {
        total: 5,
        successful: 5,
        failed: 0
    },
    hits: {
        total: 2,
        max_score: 1,
        hits: [{
            _index: "people",
            _type: "firefighter",
            _id: "2",
            _score: 1,
            _source: {
                helmetSize: 12,
                id: "2",
                firstName: "Frank",
                lastName: "TheFirefighter"
            }
        }, {
            _index: "people",
            _type: "teacher",
            _id: "1",
            _score: 1,
            _source: {
                gradeNumber: 8,
                id: "1",
                firstName: "Steve",
                lastName: "TheTeacher"
            }
        }]
    }
}

How do I get NEST to return a mixed list of instances derived from a base class?

Many thanks!

-Z

1 Answers
Related