使用高级 Nest 客户端和 AutoMap 进行 PUT 映射
PUT Mapping Using High Level Nest Client and AutoMap
我正在使用以下代码片段创建 Elasticsearch 索引:
ICreateIndexResponse createIndexResponse = elasticClient.CreateIndex(IndexName, c => c
.Mappings(ms => ms
.Map<Document>(m => m.AutoMap())
)
);
Document
class 是具有属性映射的 POCO。
我希望能够将字段添加到我的映射中。这看起来可以使用 Put Mapping API:
PUT my_index
{
"mappings": {
"_doc": {
"properties": {
"name": {
"properties": {
"first": {
"type": "text"
}
}
},
"user_id": {
"type": "keyword"
}
}
}
}
}
PUT my_index/_mapping/_doc
{
"properties": {
"name": {
"properties": {
"last": {
"type": "text"
}
}
},
"user_id": {
"type": "keyword",
"ignore_above": 100
}
}
}
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-mapping.html
请注意,第一个 PUT 正在创建索引和映射。第二个 PUT 是添加和修改字段。我希望能够执行第二个 PUT。
理想的方案是将属性添加到我的 Document
class,调用 AutoMap
,并使用客户端调用 PUT 映射 API。新属性将添加到我的映射中,并且以前存在的属性 updated/ignored 是适当的。
这可能吗?我是否应该使用某些参数再次调用 CreateIndex
方法?
Put 映射 API 在客户端公开为 .Map<T>
var client = new ElasticClient();
var putMappingResponse = client.Map<Document>(m => m
.AutoMap()
);
这将自动映射 Document
的所有属性。我相信 Elasticsearch 将简单地不对那些已经存在的映射进行操作,并添加新的映射。
如果您只想发送那些尚未映射的属性,可以通过获取 Document
的自动映射属性,从索引中检索映射,excepting 后者来自前者,然后发送带有 .Map<T>()
的那些。像
var defaultIndex = "properties_example";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(settings);
if (!client.IndexExists(defaultIndex).Exists)
{
var createIndexResponse = client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<Document>(mm => mm.AutoMap())
)
);
}
var properties = new PropertyWalker(typeof(Document), null).GetProperties();
// will use the index inferred for Document, or the default index if none
// specified. Can specify an index on this call if you want to
var getMappingResponse = client.GetMapping<Document>();
var indexedMappings = getMappingResponse
// Use the index name to which the call was made.
.Indices[defaultIndex]
.Mappings[typeof(Document)]
.Properties;
var propertiesToIndex = new Dictionary<PropertyName, IProperty>();
foreach(var property in properties)
{
if (!indexedMappings.ContainsKey(property.Key))
{
propertiesToIndex.Add(property.Key, property.Value);
}
}
// map new properties only if there are some to map
if (propertiesToIndex.Any())
{
var request = new PutMappingRequest<Document>()
{
Properties = new Properties(propertiesToIndex)
};
var putMappingResponse = client.Map(request);
}
我正在使用以下代码片段创建 Elasticsearch 索引:
ICreateIndexResponse createIndexResponse = elasticClient.CreateIndex(IndexName, c => c
.Mappings(ms => ms
.Map<Document>(m => m.AutoMap())
)
);
Document
class 是具有属性映射的 POCO。
我希望能够将字段添加到我的映射中。这看起来可以使用 Put Mapping API:
PUT my_index
{
"mappings": {
"_doc": {
"properties": {
"name": {
"properties": {
"first": {
"type": "text"
}
}
},
"user_id": {
"type": "keyword"
}
}
}
}
}
PUT my_index/_mapping/_doc
{
"properties": {
"name": {
"properties": {
"last": {
"type": "text"
}
}
},
"user_id": {
"type": "keyword",
"ignore_above": 100
}
}
}
https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-put-mapping.html
请注意,第一个 PUT 正在创建索引和映射。第二个 PUT 是添加和修改字段。我希望能够执行第二个 PUT。
理想的方案是将属性添加到我的 Document
class,调用 AutoMap
,并使用客户端调用 PUT 映射 API。新属性将添加到我的映射中,并且以前存在的属性 updated/ignored 是适当的。
这可能吗?我是否应该使用某些参数再次调用 CreateIndex
方法?
Put 映射 API 在客户端公开为 .Map<T>
var client = new ElasticClient();
var putMappingResponse = client.Map<Document>(m => m
.AutoMap()
);
这将自动映射 Document
的所有属性。我相信 Elasticsearch 将简单地不对那些已经存在的映射进行操作,并添加新的映射。
如果您只想发送那些尚未映射的属性,可以通过获取 Document
的自动映射属性,从索引中检索映射,excepting 后者来自前者,然后发送带有 .Map<T>()
的那些。像
var defaultIndex = "properties_example";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(settings);
if (!client.IndexExists(defaultIndex).Exists)
{
var createIndexResponse = client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<Document>(mm => mm.AutoMap())
)
);
}
var properties = new PropertyWalker(typeof(Document), null).GetProperties();
// will use the index inferred for Document, or the default index if none
// specified. Can specify an index on this call if you want to
var getMappingResponse = client.GetMapping<Document>();
var indexedMappings = getMappingResponse
// Use the index name to which the call was made.
.Indices[defaultIndex]
.Mappings[typeof(Document)]
.Properties;
var propertiesToIndex = new Dictionary<PropertyName, IProperty>();
foreach(var property in properties)
{
if (!indexedMappings.ContainsKey(property.Key))
{
propertiesToIndex.Add(property.Key, property.Value);
}
}
// map new properties only if there are some to map
if (propertiesToIndex.Any())
{
var request = new PutMappingRequest<Document>()
{
Properties = new Properties(propertiesToIndex)
};
var putMappingResponse = client.Map(request);
}