Reputation: 244
I have two indexes set up in Elasticsearch storing different types of data and I'm attempting to get search results using nest from both indexes at the same time. I have set up models like the following...
public class Person
{
[Number(Name="person_id")]
public int Id { get; set; }
[Date(Name = "person_created")]
public DateTime Created { get; set; }
...
}
public class Work {
[Number(Name="work_id")]
public int Id { get; set; }
[Date(Name = "work_created")]
public DateTime Created { get; set; }
...
}
When querying on a single index I'm able to do the following and get my results back mapped to my model type...
var request = new SearchRequest("works")
{
From = searchQuery.Offset,
Size = searchQuery.PageSize,
Query = new QueryStringQuery { Query = searchQuery.SearchTerm },
};
var result = _elasticClient.Search<Work>(request);
However when doing a query like the following how do I tell nest what types to map results to per index?
var request = new SearchRequest("works,person")
{
...
}
var result = _elasticClient.Search<object> ...
Other answers I've seen suggest doing something like the following but I think the Types function has been removed in NEST 7.0...
client.Search<object>(s => s
.Size(100)
.SearchType(SearchType.Count)
.Type(Types.Type(typeof(Dog), typeof(Cat)))
Upvotes: 1
Views: 1236
Reputation: 9979
If you are in control of document indexing you could take advantage of the possibility to customize JSON serialization process in NEST, by placing .NET type within a document in an elasticsearch index. This way NEST will deserialize documents into correct types.
class Program
{
public class Person
{
[Number(Name="person_id")]
public int Id { get; set; }
[Date(Name = "person_created")]
public DateTime Created { get; set; }
}
public class Work
{
[Number(Name="work_id")]
public int Id { get; set; }
[Date(Name = "work_created")]
public DateTime Created { get; set; }
}
static void Main(string[] args)
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings =
new ConnectionSettings(pool,
sourceSerializer: (builtin, settings) => new JsonNetSerializer(builtin, settings,
() => new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All}
));
var client = new ElasticClient(connectionSettings);
var deleteIndexResponse = client.Indices.Delete("person,work");
var createIndexResponse = client.Indices
.Create("person", i => i.Map<Person>(m => m.AutoMap()));
var createIndexResponse2 = client.Indices
.Create("work", i => i.Map<Work>(m => m.AutoMap()));
client.Index(new Person {Id = 1, Created = DateTime.UtcNow},
i => i.Index("person"));
client.Index(new Work {Id = 1, Created = DateTime.UtcNow},
i => i.Index("work"));
client.Indices.Refresh();
var searchResponse = client.Search<object>(s => s
.Index("person,work")
.Query(q => q.MatchAll()));
foreach (var document in searchResponse.Documents)
{
Console.WriteLine($"Person? {document is Person} Work? {document is Work}");
}
}
}
Prints:
Person? True Work? False
Person? False Work? True
NEST.JsonNetSerializer package needs to be installed in your project.
Hope that helps.
Upvotes: 1