【问题标题】:ElasticSearch.NET - Indexing parent / child nodes in different indexesElasticSearch.NET - 索引不同索引中的父/子节点
【发布时间】:2019-10-11 12:00:52
【问题描述】:

我正在尝试按照本教程创建项目之间的父子关系;

https://www.elastic.co/guide/en/elasticsearch/client/net-api/master/parent-child-relationships.html

我的用例略有不同,因为本教程在同一索引中的相同类型的项目之间创建父/子关系。我想在两种不同类型的对象之间创建一个,这些对象需要存储在不同的索引中。我想出了这样的东西;

class MyParentType
{
    public int Id {get;set;}
    public string Data {get;set;}
    public JoinField MyJoinField { get; } = typeof(MyParentType);
}

class MyChildType
{
    public int Id {get;set;}
    public string Data {get;set;}
    public JoinField ParentJoinField { get; set; }

    public MyChildType(MyParentType parent)
    {
        ParentJoinField = JoinField.Link<MyChildType, MyParentType>(parent);
    }
}

public static void Main(string[] args)
{
    var connectionSettings = new ConnectionSettings(
            pool, (builtin, settings) => new JsonNetSerializer(builtin, settings,
                () => new JsonSerializerSettings { Converters = { new StringEnumConverter() } }))
        .DefaultMappingFor<MyParentType>(m => m.IndexName("parents_index"))
        .DefaultMappingFor<MyChildType>(m => m.IndexName("children_index").RelationName("parents"));

    var client = new ElasticClient(connectionSettings);

    client.CreateIndex("parents_index", c => c
        .Index<MyParentType>()
        .Mappings(m => m.Map<MyParentType>(n => n
            .RoutingField(r => r.Required())
            .AutoMap<MyParentType>())));

    client.CreateIndex("children_index", c => c
        .Mappings(m => m.Map<MyChildType>(n => n
            .RoutingField(r => r.Required())
            .AutoMap<MyChildType>()
            .Properties(props => props
                .Join(j => j
                    .Name(l => l.ParentNoteJoinField)
                    .Relations(r => r
                        .Join<MyParentType, MyChildType>()))))));

    var descriptor = new BulkDescriptor();
    descriptor.IndexMany(GetSomeCollectionOfParents());
    var response = client.Bulk(descriptor);
}

但是,最后一行从 ElasticSearch 返回失败的响应;

操作[0]:索引返回 400 _index:parents_index _type:myparenttype _id:123 _version:0 错误:类型:mapper_parsing_exception 原因:“[myJoinField] 的对象映射试图将字段 [myJoinField] 解析为对象,但找到了具体价值”

谁能指出我做错了什么?

【问题讨论】:

  • Elasticsearch 中的 Parent/Child 关系要求 Parent 和 Child 文档位于同一个索引中;事实上,子文档与父文档位于同一个分片中。您始终可以使用另一个索引中文档 id 的字段值来索引一个索引中的文档,但这不能使用父/子关系、join 字段或任何父/子查询
  • 谢谢@RussCam,我一直在尝试将 Elasticsearch 视为关系数据库;即一个索引中的类型是连续的,并且与其他索引中的其他类型相关。我需要摆脱这种心态。

标签: c# elasticsearch nest elastic-stack


【解决方案1】:

我的父对象似乎不需要任何JoinField。应该是这样的;

class MyParentType
{
    public int Id {get;set;}
    public string Data {get;set;}
}

以及索引;

client.CreateIndex("parents_index", c => c
    .Index<MyParentType>()
    .Mappings(m => m.Map<MyParentType>(n => n
        .AutoMap<MyParentType>())));

client.CreateIndex("children_index", c => c
    .Index<MyChildType>()
    .Mappings(m => m.Map<MyChildType>(n => n
        .RoutingField(r => r.Required())
        .AutoMap<MyChildType>()
        .Properties(props => props
            .Join(j => j
                .Name(l => l.ParentNoteJoinField)
                .Relations(r => r
                    .Join<MyParentType, MyChildType>()))))));

这似乎有效,我得到了一个类似的索引子对象;

{
  "_source": {
    "id": "1",
    "parentJoinField": {
      "name": "parents",
      "parent": "123"
    },
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 2011-08-20
    • 2023-03-14
    • 2015-05-13
    相关资源
    最近更新 更多