如何用NEST在弹性搜索中创建多态数据索引

时间:2017-08-08 20:27:32

标签: elasticsearch

我有

             var descriptor = new CreateIndexDescriptor("resources")
                .Mappings(ms => ms
                    .Map<ResourceEntity>(m => m
                        .AutoMap()
                        .RoutingField(k => k.Required(true))
                        .Properties(props => props
                            .Keyword(s1 => s1.Name(p => p.Id).Norms(false))
                            .Keyword(k => k.Name(p => p.Type).Norms(false))
                            .Keyword(k => k.Name(p => p.Location).Norms(false))
                         )
                    )
                    .Map<StreamEntity>(m => m
                        .AutoMap()
                        .RoutingField(r => r.Required(true))
                        .Properties(props => props
                            .Keyword(s1 => s1.Name(p => p.Name).Norms(false))
                         )
                    )
                    .Map<StreamMessageEntity>(m => m
                        .AutoMap()
                        .Parent<StreamEntity>()
                        .RoutingField(r => r.Required(true))
                    )
                );

但它失败了

Invalid NEST response built from a unsuccessful low level call on PUT: /elastic/resources
# Audit trail of this API call:
 - [1] BadResponse: Node: https://local.earthml.com:8500/elastic/ Took: 00:00:00.6271828
# ServerError: ServerError: 400Type: illegal_argument_exception Reason: "Mapper for [id] conflicts with existing mapping in other types:
[mapper [id] has different [similarity], mapper [id] is used by multiple types. Set update_all_types to true to update [null_value] across all types.]"
# OriginalException: System.Net.WebException: The remote server returned an error: (400) Bad Request.
   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Elasticsearch.Net.HttpConnection.<RequestAsync>d__14`1.MoveNext()
# Request:
<Request stream not captured or already read to completion by serializer. Set DisableDirectStreaming() on ConnectionSettings to force it to be set on the response.>
# Response:
<Response stream not captured or already read to completion by serializer. Set DisableDirectStreaming() on ConnectionSettings to force it to be set on the response.>

这是我的基类。

public abstract class ResourceEntity
{         
    public string Id { get; set; }       
    public string Location { get; set; }
    public string Type { get; set; }
}

public class NamedResourceEntity : ResourceEntity
{      
    public string Name { get; set; }
}
public class StreamEntity : NamedResourceEntity
{
}

public class StreamMessageEntity : ResourceEntity
{       
}

截至目前,他们没有太多额外的属性,但他们会来。我是否必须注册所有内容,或者我可以使用弹性搜索中的索引简单地注册基类。

我希望所有类型都在同一个索引中,并且Type属性是不同类的分隔符(对于每个类,它们在创建时都是唯一的。)

1 个答案:

答案 0 :(得分:0)

我必须为所有类型显式地显示地图属性

            descriptor.Mappings(ms => ms
                    .Map<ResourceEntity>(m => m
                        .AutoMap()
                        .RoutingField(k => k.Required())
                    .Properties(props => props
                        .Keyword(s1 => s1.Name(p => p.Id).Norms(false))
                        .Keyword(k => k.Name(p => p.Type).Norms(false))
                        .Keyword(k => k.Name(p => p.Location).Norms(false))
                     )
                    )
                    .Map<StreamEntity>(m => m
                        .AutoMap()
                        .RoutingField(r => r.Required())
                    .Properties(props => props
                        .Keyword(s1 => s1.Name(p => p.Id).Norms(false))
                        .Keyword(k => k.Name(p => p.Type).Norms(false))
                        .Keyword(k => k.Name(p => p.Name).Norms(false))
                        .Keyword(k => k.Name(p => p.Location).Norms(false))
                     )
                    )
                    .Map<StreamMessageEntity>(m => m
                        .AutoMap()
                        .Parent<StreamEntity>()
                        .Properties(props => props
                            .Keyword(s1 => s1.Name(p => p.Id).Norms(false))
                            .Keyword(k => k.Name(p => p.Type).Norms(false))
                            .Keyword(k => k.Name(p => p.Location).Norms(false))
                         )
                        .RoutingField(r => r.Required())
                    ).Map<StreamMessageAttachmentEntity>(m => m
                    .AutoMap()
                    .Parent<StreamMessageEntity>()
                    .RoutingField(r => r.Required()))
                );