Поиск по нескольким индексам и возврат правильных типов - PullRequest
0 голосов
/ 04 июля 2019

У меня в Elasticsearch настроены два индекса, в которых хранятся данные разных типов, и я пытаюсь получить результаты поиска, используя гнездо из обоих индексов одновременно.Я настроил модели, как показано ниже ...

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; }
    ...
}

При запросе по одному индексу я могу сделать следующее и получить результаты, сопоставленные с типом моей модели ...

var request = new SearchRequest("works")
{
    From = searchQuery.Offset,
    Size = searchQuery.PageSize,
    Query = new QueryStringQuery { Query = searchQuery.SearchTerm },
 };

 var result = _elasticClient.Search<Work>(request);

Однако при выполнении запроса, подобного следующему, как указать nest, с какими типами сопоставлять результаты по индексу?

var request = new SearchRequest("works,person")
{
     ...
}
var result = _elasticClient.Search<object> ...

Другие ответы, которые я видел, предлагают сделать что-то вроде следующего, ноЯ думаю, что функция типов была удалена в NEST 7.0 ...

client.Search<object>(s => s
    .Size(100)
    .SearchType(SearchType.Count)
    .Type(Types.Type(typeof(Dog), typeof(Cat)))

1 Ответ

1 голос
/ 04 июля 2019

Если вы контролируете индексирование документов, вы можете воспользоваться возможностью для настройки процесса сериализации JSON в NEST, поместив тип .NET в документ в индексе эластичного поиска. Таким образом, NEST будет десериализовывать документы в правильные типы.

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}");
        }
    }
}

Печать:

Person? True Work? False
Person? False Work? True

NEST.JsonNetSerializer пакет должен быть установлен в вашем проекте.

Надеюсь, это поможет.

...