在 .NET Core 应用程序中使用 NEST 在 ElasticSearch 中的正确索引路径内批量收集

Bulk collection inside the right Index path in ElasticSearch using NEST in a .NET Core application

我正在尝试在 .NET Core 应用程序中使用 NEST 在 ElasticSearch 索引中批量处理元素集合。

目前我所拥有的正在运行,元素已保存,但未保存在我尝试做的地方

我的客户创建:

protected ElasticClient GetClient()
{
    var node = new Uri("http://localhost:9200/");
    var settings = new ConnectionSettings(node)
        .DefaultIndex("TestIndex")
        .PrettyJson(true);

    return new ElasticClient(settings);
}

下面是我如何为批量所有数据创建描述符

protected BulkDescriptor GenerateBulkDescriptor<T>(IEnumerable<T> elements, string indexName) where T: class, IIndexable
{
    var bulkIndexer = new BulkDescriptor();

    foreach (var element in elements)
        bulkIndexer.Index<T>(i => i
          .Document(element)
          .Id(element.Id)
          .Index(indexName));

    return bulkIndexer;
}

最后,一旦我有了这个,这就是我如何索引数据

var descriptor = GenerateBulkDescriptor(indexedElements, "indexed_elements");

var response = GetClient().Bulk(descriptor);

但是,如果我看到它是如何使用 this 存储在弹性索引中的,那就是我所拥有的:

如何知道是否在 TestIndex 索引下创建?因为据我所知,只创建了一个索引

非常感谢您

BulkDescriptor 上定义索引操作时,您明确设置了用于每个操作的索引

foreach (var element in elements)
    bulkIndexer.Index<T>(i => i
      .Document(element)
      .Id(element.Id)
      .Index(indexName));

其中 indexName"indexed_elements"。这就是为什么所有文档都编入该索引而您在 "TestIndex".

中看不到任何文档的原因

Bulk API 允许定义多个操作,其中可能包括将文档索引到不同的索引中。当直接在操作上指定索引时,将使用该索引。 如果 Bulk API 调用中的所有索引操作都针对同一个索引进行,您可以省略每个操作的索引,而是指定要在批量API直接调用

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

var settings = new ConnectionSettings(pool)
    .DefaultIndex(defaultIndex);

var client = new ElasticClient(settings);

var people = new [] 
{
    new Person { Id = 1, Name = "Paul" },
    new Person { Id = 2, Name = "John" },
    new Person { Id = 3, Name = "George" },
    new Person { Id = 4, Name = "Ringo" },
};

var bulkResponse = client.Bulk(b => b
    .Index("people")
    .IndexMany(people)
);

发送以下请求

POST http://localhost:9200/people/_bulk
{"index":{"_id":"1","_type":"person"}}
{"id":1,"name":"Paul"}
{"index":{"_id":"2","_type":"person"}}
{"id":2,"name":"John"}
{"index":{"_id":"3","_type":"person"}}
{"id":3,"name":"George"}
{"index":{"_id":"4","_type":"person"}}
{"id":4,"name":"Ringo"}

请注意,URI 是 /people/bulk,并且表示操作的每个 JSON 对象不包含 "_index"

如果您省略 .Index() on Bulk API 调用,它将使用在 ConnectionSettings:

上配置的 DefaultIndex
var bulkResponse = client.Bulk(b => b
    .IndexMany(people)
);

产生

POST http://localhost:9200/_bulk
{"index":{"_id":"1","_index":"default_index","_type":"person"}}
{"id":1,"name":"Paul"}
{"index":{"_id":"2","_index":"default_index","_type":"person"}}
{"id":2,"name":"John"}
{"index":{"_id":"3","_index":"default_index","_type":"person"}}
{"id":3,"name":"George"}
{"index":{"_id":"4","_index":"default_index","_type":"person"}}
{"id":4,"name":"Ringo"}

您还可以使用 DefaultMappingFor<T>()ConnectionSettings 上指定用于给定 POCO 类型的默认索引,其中 T 是您的 POCO 类型。

经过一些测试和尝试,我找到了解决方案。

首先,索引配置有问题,一旦我将其设置为小写,索引就可以很好地在内部索引数据。

然后,我在同一索引内的特定 "path" 中遇到了索引数据的问题,最后我从 NEST 中找到了 类型的解决方案,同时利用Russ 在上一个答案中建议的 DefaultMappingFor。

客户端定义:

var node = new Uri(_elasticSearchConfiguration.Node);
var settings = new ConnectionSettings(node)
    .DefaultMappingFor<IndexedElement>(m => m
        .IndexName(_elasticSearchConfiguration.Index)
        .TypeName(nameof(IndexedElement).ToLower()))
    .PrettyJson(true)
    .DisableDirectStreaming();

var client = new ElasticClient(settings);

然后,BulkDescriptior 的创建:

var bulkIndexer = new BulkDescriptor();

foreach (var element in elements)
    bulkIndexer.Index<IndexedElement>(i => i
        .Document(element)
        .Type(nameof(IndexedElement).ToLower()))
        .Id(element.Id)
    );

最后,数据批量:

client.Bulk(bulkIndexer);

现在,如果我调用索引,我可以看到这个

{
"testindex": {
    "aliases": {},
    "mappings": {
        "indexedelement": {

[...]

}

感谢 Russ 的帮助以及看过 post 的人。

更新

最后,似乎唯一的问题是关于默认索引,它必须是小写的,所以,用 POCO 本身的名称指定类型是不必要的,就像@RussCam 在上面的评论中确实检测到的那样.将默认索引更改为小写后,所有不同的可能性都可以正常工作。

再次感谢大家