-6ren">
gpt4 book ai didi

c# - 如何使用流畅的映射来映射Dictionary 类型的属性

转载 作者:行者123 更新时间:2023-12-03 00:50:41 25 4
gpt4 key购买 nike

我有一本字典,希望使用流畅的映射进行映射,对于MyDto类的某些属性,我需要添加规范化器。

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))

我的类(class)定义:
class MyEntity {
...
Dictionary<string, MyDto> SomeProperty {get;set;}
...
}
class MyDto {
...
string Name {get;set;}
...
}

最佳答案

不可能将其添加为显式映射,但这是通过动态模板进行的。

让我们看一下为什么无法通过显式映射来实现。考虑Dictionary<string, MyDto> SomeProperty如何序列化为JSON。例如

client.IndexDocument(new MyEntity 
{
SomeProperty = new Dictionary<string, UserQuery.MyDto>
{
{ "field_1", new MyDto { Name = "foo" } },
{ "field_2", new MyDto { Name = "bar" } }
}
});

默认情况下将序列化为
{
"someProperty": {
"field_1": {
"name": "foo"
},
"field_2": {
"name": "bar"
}
}
}

如果我们想将显式映射应用于 MyDto.Name,则需要在映射时知道将要使用的所有字典键。

但是,您可以 configure a dynamic template that will map any MyDto.Name as a keyword type, using path_match

private static void Main()
{
var defaultIndex = "my_index";
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)
client.DeleteIndex(defaultIndex);

var createIndexResponse = client.CreateIndex(defaultIndex, c => c
.Settings(s => s
.NumberOfShards(1)
.NumberOfReplicas(0)
)
.Mappings(m => m
.Map<MyEntity>(mm => mm
.AutoMap()
.DynamicTemplates(dt => dt
.DynamicTemplate("MyDto", dtd => dtd
.PathMatch("someProperty.*.name")
.Mapping(dm => dm
.Keyword(k => k)
)
)
)
.Properties(p => p
.Object<Dictionary<string, MyDto>>(o => o
.Name(n => n.SomeProperty)
)
)
)
)
);

var indexResponse = client.Index(new MyEntity
{
SomeProperty = new Dictionary<string, UserQuery.MyDto>
{
{ "field_1", new MyDto { Name = "foo" } },
{ "field_2", new MyDto { Name = "bar" } }
}
}, i => i.Refresh(Refresh.WaitFor));

var mappingResponse = client.GetMapping<MyEntity>();
}

public class MyEntity
{
public Dictionary<string, MyDto> SomeProperty { get; set; }
}

public class MyDto
{
public string Name { get; set; }
}

映射响应确认 someProperty.field_1.namesomeProperty.field_2.name被映射为 keyword
{
"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"
}
}
}
}
}
}
}
}
}
}

除了 map 爆炸

如果用户可以添加所需的任意键名,则可能需要考虑向 MyDto添加属性以保存字典键,并使用 List<MyDto>或类似的集合 mapped as a nested datatype而不是 Dictionary<string, MyDto>。由于字典键的基数很高,因此存在映射爆炸和击中 maximum number of fields soft limit和许多稀疏字段的风险,这会影响性能。使用 List<MyDto>属性类型,您将不会遇到此问题,并且仍然可以在键字段上进行查询,但要付出代价,即 List<MyDto>对您的应用程序代码而言可能不是 Dictionary<string, MyDto>最佳。要考虑的事情:)

关于c# - 如何使用流畅的映射来映射Dictionary <string,MyDto>类型的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54099598/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com