在 .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 在上面的评论中确实检测到的那样.将默认索引更改为小写后,所有不同的可能性都可以正常工作。
再次感谢大家
我正在尝试在 .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 在上面的评论中确实检测到的那样.将默认索引更改为小写后,所有不同的可能性都可以正常工作。
再次感谢大家