Elasticsearch выводит _id по динамическому типу при использовании IndexMany - PullRequest
1 голос
/ 11 июля 2019

Я пытаюсь решить мою проблему.Я создаю приложение, в котором мы индексируем assets в Elastic.Природа активов очень динамична, потому что они содержат метаданные клиента, которые отличаются от клиента к клиенту.

Из-за этого Индекс строится из Списка динамики в C #,Это на самом деле работает как шарм.Проблема в том, что я не могу управлять свойством _id в Elastic при использовании интерфейса C #.Это означает, что когда я обновляю документы, вместо обновления правильного создается новый дубликат.

Мой код выглядит так:

List<dynamic> assets = new List<dynamic>();
var settings1 = new ConnectionSettings(
    new Uri("http://localhost:9200")
    ).DefaultIndex("assets");

var client = new ElasticClient(settings1);

//assets is build here

var indexResponse = client.Indices.Create("assets");
var BulkResponse = client.IndexMany(assets);

Это на самом деле работает, и индекс строится какЯ ожидаю, что - почти.Несмотря на то, что у меня есть динамическое свойство Id, оно не выводится правильно, что означает, что документ получает _Id, определенный Elastic.Таким образом, в следующий раз, когда я выполню этот код, используя тот же Id, новый документ будет создан, а не обновлен.

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

var bulkResponse = client.Bulk(bd => bd.IndexMany(assets, (descriptor, s) => descriptor.Id(s.Id)));

Но это выдает ошибку, которую я не могу поймать в ядре .net.Это на самом деле работает на более ранних версиях Elastic, но, похоже, было сломано с 7.2 и 7.0.1 интерфейса C #.

Любая помощь очень ценится.

Ответы [ 2 ]

2 голосов
/ 12 июля 2019

Чтобы разрешить работать следующим

var bulkResponse = client.Bulk(bd => bd.IndexMany(assets, (descriptor, s) => descriptor.Id(s.Id)));

Вам просто нужно привести тип Id к тому типу, которым он является. Например, если это string

var client = new ElasticClient();

var assets = new dynamic[] 
{
    new { Id = "1", Name = "foo" },
    new { Id = "2", Name = "bar" },
    new { Id = "3", Name = "baz" },     
};

var bulkResponse = client.Bulk(bd => bd.IndexMany(assets, (descriptor, s) => descriptor.Id((string)s.Id)));

Это ограничение времени выполнения.

2 голосов
/ 11 июля 2019

Вместо использования типа dynamic вы можете создать пользовательский тип на основе словаря, например:

    public class DynamicDocument : Dictionary<string, object>
    {
        public string Id => this["id"]?.ToString();
    }

и используйте его следующим образом:

class Program
{
    public class DynamicDocument : Dictionary<string, object>
    {
        public string Id => this["id"]?.ToString();
    }

    static async Task Main(string[] args)
    {
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
        var connectionSettings = new ConnectionSettings(pool);
        connectionSettings.DefaultIndex("documents");

        var client = new ElasticClient(connectionSettings);

        await client.Indices.DeleteAsync("documents");
        await client.Indices.CreateAsync("documents");

        var response = await client.IndexAsync(
            new DynamicDocument
            {
                {"id", "1"}, 
                {"field1", "value"}, 
                {"field2", 1}
            }, descriptor => descriptor);

        //will update document with id 1 as it's already exists
        await client.IndexManyAsync(new[]
        {
            new DynamicDocument
            {
                {"id", "1"},
                {"field1", "value2"},
                {"field2", 2}
            }
        }); 

        await client.Indices.RefreshAsync();

        var found = await client.GetAsync<DynamicDocument>("1");

        Console.WriteLine($"Id: {found.Source.Id}");
        Console.WriteLine($"field1: {found.Source["field1"]}");
        Console.WriteLine($"field2: {found.Source["field2"]}");
    }
}

Выход:

Id: 1
field1: value2
field2: 2

Протестировано с эластичным поиском 7.2.0 и NEST 7.0.1.

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

...