C# 如何映射Dictionary类型的属性<;字符串,MyDto>;使用fluent映射
我有一个字典,我想使用fluent映射来映射它,对于MyDto类的一些属性,我需要添加normalizerC# 如何映射Dictionary类型的属性<;字符串,MyDto>;使用fluent映射,c#,elasticsearch,nest,C#,elasticsearch,Nest,我有一个字典,我想使用fluent映射来映射它,对于MyDto类的一些属性,我需要添加normalizer new CreateIndexDescriptor("indexName") .Mappings(ms => ms.Map<Entity>(e => new PutMappingDescriptor<Entity>() .AutoMap() .Properties(o => o.Object<IDictionary<string,
new CreateIndexDescriptor("indexName")
.Mappings(ms => ms.Map<Entity>(e => new PutMappingDescriptor<Entity>()
.AutoMap()
.Properties(o => o.Object<IDictionary<string, MyDto>>(
m => m.AutoMap().Name(f => f.SomeProperty))
new CreateIndexDescriptor(“indexName”)
.Mappings(ms=>ms.Map(e=>new-PutMappingDescriptor())
.AutoMap()
.Properties(o=>o.Object(
m=>m.AutoMap().Name(f=>f.SomeProperty))
我的班级定义:
class MyEntity {
...
Dictionary<string, MyDto> SomeProperty {get;set;}
...
}
class MyDto {
...
string Name {get;set;}
...
}
类MyEntity{
...
字典SomeProperty{get;set;}
...
}
类MyDto{
...
字符串名称{get;set;}
...
}
不可能将其作为显式映射添加,但它是通过动态模板添加的
让我们看看为什么它不可能通过显式映射。考虑<代码>字典属性>代码>将如何序列化到JSON。例如< /P>
client.IndexDocument(new MyEntity
{
SomeProperty = new Dictionary<string, UserQuery.MyDto>
{
{ "field_1", new MyDto { Name = "foo" } },
{ "field_2", new MyDto { Name = "bar" } }
}
});
如果我们想将显式映射应用于MyDto.Name
,我们需要在映射时知道将使用的所有字典键
但是你可以
private static void Main()
{
var defaultIndex=“我的索引”;
变量池=新的SingleNodeConnectionPool(新Uri(“http://localhost:9200"));
var设置=新连接设置(池)
.DefaultIndex(默认索引);
var客户端=新的ElasticClient(设置);
if(client.indexists(defaultIndex.Exists)
client.DeleteIndex(defaultIndex);
var createIndexResponse=client.CreateIndex(defaultIndex,c=>c
.Settings(s=>s
.NumberOfShard(1)
.numberofreplications(0)
)
.Mappings(m=>m
.Map(mm=>mm
.AutoMap()
.动态模板(dt=>dt
.DynamicTemplate(“MyDto”,dtd=>dtd
.PathMatch(“someProperty.*.name”)
.Mapping(dm=>dm
.Keyword(k=>k)
)
)
)
.Properties(p=>p
.Object(o=>o
.Name(n=>n.SomeProperty)
)
)
)
)
);
var indexResponse=client.Index(新MyEntity
{
SomeProperty=新字典
{
{“field_1”,新的MyDto{Name=“foo”},
{“field_2”,新的MyDto{Name=“bar”}
}
},i=>i.Refresh(Refresh.WaitFor));
var mappingResponse=client.GetMapping();
}
公共类MyEntity
{
公共字典SomeProperty{get;set;}
}
公共类MyDto
{
公共字符串名称{get;set;}
}
映射响应确认someProperty.field\u 1.name
和someProperty.field\u 2.name
映射为关键字
{
"my_index" : {
"mappings" : {
"myentity" : {
"dynamic_templates" : [
{
"MyDto" : {
"path_match" : "someProperty.*.name",
"mapping" : {
"type" : "keyword"
}
}
}
],
"properties" : {
"someProperty" : {
"properties" : {
"field_1" : {
"properties" : {
"name" : {
"type" : "keyword"
}
}
},
"field_2" : {
"properties" : {
"name" : {
"type" : "keyword"
}
}
}
}
}
}
}
}
}
}
关于地图爆炸的旁白
您可能想考虑将属性添加到<代码> MyDto <代码>中,以持有字典键,并使用<代码>列表>代码>或类似集合,而不是使用<代码>字典>代码>,如果用户可以添加任意键名称,则使用字典键的高基数,您就可能面临映射爆炸的风险,并且命中大量的O。F稀疏字段,这会影响性能。使用<代码>列表属性类型,您将不会有这个问题,并且仍然可以在密钥字段上进行查询,但代价是<>代码>清单>代码>对于应用程序代码可能不如<<代码>字典<代码>。不可能将其作为显式映射添加,但它是通过动态模板添加的
让我们看看为什么它不可能通过显式映射。考虑<代码>字典属性>代码>将如何序列化到JSON。例如< /P>
client.IndexDocument(new MyEntity
{
SomeProperty = new Dictionary<string, UserQuery.MyDto>
{
{ "field_1", new MyDto { Name = "foo" } },
{ "field_2", new MyDto { Name = "bar" } }
}
});
如果我们想将显式映射应用于MyDto.Name
,我们需要在映射时知道将使用的所有字典键
但是你可以
private static void Main()
{
var defaultIndex=“我的索引”;
变量池=新的SingleNodeConnectionPool(新Uri(“http://localhost:9200"));
var设置=新连接设置(池)
.DefaultIndex(默认索引);
var客户端=新的ElasticClient(设置);
if(client.indexists(defaultIndex.Exists)
client.DeleteIndex(defaultIndex);
var createIndexResponse=client.CreateIndex(defaultIndex,c=>c
.Settings(s=>s
.NumberOfShard(1)
.numberofreplications(0)
)
.Mappings(m=>m
.Map(mm=>mm
.AutoMap()
.动态模板(dt=>dt
.DynamicTemplate(“MyDto”,dtd=>dtd
.PathMatch(“someProperty.*.name”)
.Mapping(dm=>dm
.Keyword(k=>k)
)
)
)
.Properties(p=>p
.Object(o=>o
.Name(n=>n.SomeProperty)
)
)
)
)
);
var indexResponse=client.Index(新MyEntity
{
SomeProperty=新字典
{
{“field_1”,新的MyDto{Name=“foo”},
{“field_2”,新的MyDto{Name=“bar”}
}
},i=>i.Refresh(Refresh.WaitFor));
var mappingResponse=client.GetMapping();
}
公共类MyEntity
{
公共字典SomeProperty{get;set;}
}
公共类MyDto
{
公共字符串名称{get;set;}
}
映射响应确认someProperty.field\u 1.name
和someProperty.field\u 2.name
映射为关键字
{
"my_index" : {
"mappings" : {
"myentity" : {
"dynamic_templates" : [
{
"MyDto" : {
"path_match" : "someProperty.*.name",
"mapping" : {
"type" : "keyword"
}
}
}
],
"properties" : {
"someProperty" : {
"properties" : {
"field_1" : {
"properties" : {
"name" : {
"type" : "keyword"
}
}
},
"field_2" : {
"properties" : {
"name" : {
"type" : "keyword"
}
}
}
}
}
}
}
}
}
}
关于地图爆炸的旁白
您可能想考虑将属性添加到<代码> MyDto <代码>中,以保存字典键,并使用<代码>列表>代码>或类似集合,而不是使用<代码>字典>代码>,如果用户可以添加任意键名称,则使用字典键的高基数,则会发生映射爆炸和命中的风险。