动态模板将非常适合您的用例,此功能为您提供了一种控制弹性搜索如何映射您的动态数据模式的好方法。
您可以根据字段名称利用匹配参数和控制字段类型。如果实例DatasetField
已IsGeoPoint
设置为,true
我们可以使用 GeoPoint 为 elasticsearch 字段名称添加前缀,并配置动态模板以创建goe_point
以 GeoPoint 为前缀的名称的字段
{
"mappings": {
"dynamic_templates": [{
"geo_shape": {
"match": "GeoShape*",
"mapping": {
"type": "geo_shape"
}
}
}, {
"geo_point": {
"match": "GeoPoint*",
"mapping": {
"type": "geo_point"
}
}
}
]
}
}
这是一个示例 C# 应用程序,展示了它的实际应用
class Program
{
static async Task Main(string[] args)
{
string indexName = "my_index";
var connectionSettings = new ConnectionSettings(new Uri("http://localhost:9200"));
connectionSettings.DefaultIndex(indexName);
var elasticClient = new ElasticClient(connectionSettings);
await elasticClient.Indices.DeleteAsync(indexName);
//create index mapping with two dynamic templates,
//based on field suffix elasticsearch will map field to specific type
var indexResponse = await elasticClient.Indices.CreateAsync(indexName, d => d
.Map(map => map
.DynamicTemplates(dt => dt
.DynamicTemplate("geo_shape", gs => gs.Match("GeoShape*").Mapping(m => m.GeoShape(s => s)))
.DynamicTemplate("geo_point", gs => gs.Match("GeoPoint*").Mapping(m => m.GeoPoint(p => p)))
)));
//some same data matching your schema
var data = new List<DatasetField>
{
new () { Name = "Field1", IsGeoPoint = true },
new () { Name = "Field2", IsGeoShape = true },
};
var document = new EsDocument();
foreach (var datasetField in data)
{
//if the field is of type geo shape, prefix field name with GeoShape,
//geo_shape dynamic template will match field name and will create geo_point type for it
if (datasetField.IsGeoShape)
{
document.Add($"GeoShape{datasetField.Name}", new PointGeoShape(new GeoCoordinate(0, 0)));
}
//if the field is of type geo point, prefix field name with GeoPoint,
//geo_point dynamic template will match field name and will create geo_shape type for it
if (datasetField.IsGeoPoint)
{
document.Add($"GeoPoint{datasetField.Name}", new GeoLocation(0, 0));
}
}
var response = await elasticClient.IndexDocumentAsync(document);
}
//this class is just an alias to dictionary
class EsDocument : Dictionary<string,object>{}
class DatasetField
{
public string Name { get; set; }
public bool IsGeoShape { get; set; }
public bool IsGeoPoint { get; set; }
}
}
这将产生以下弹性搜索映射
{
"my_index": {
"mappings": {
"dynamic_templates": [{
"geo_shape": {
"match": "GeoShape*",
"mapping": {
"type": "geo_shape"
}
}
}, {
"geo_point": {
"match": "GeoPoint*",
"mapping": {
"type": "geo_point"
}
}
}
],
"properties": {
"GeoPointField1": {
"type": "geo_point"
},
"GeoShapeField2": {
"type": "geo_shape"
}
}
}
}
}
当涉及到批量索引文档时,最简单的方法是使用IndexManyAsync
扩展方法
await elasticClient.IndexManyAsync(new List<EsDocument>());
另请查看此博客文章,详细描述索引多个文档。检查“多个文档”部分。
更新:将新的动态模板添加到具有现有动态模板的映射中
var map = (await elasticClient.Indices.GetMappingAsync<EsDocument>()).Indices["your_index_name"];
var dynamicTemplates = map.Mappings.DynamicTemplates;
//add new
dynamicTemplates.Add(new KeyValuePair<string, IDynamicTemplate>());
await elasticClient.Indices.PutMappingAsync(new PutMappingRequest("your_index_name") { DynamicTemplates = dynamicTemplates });