我是Elasticsearch和Nest的新手,但遇到了问题。我想做的是创建一个索引,并为带有嵌套字段的文档建立索引。

    [ElasticsearchType]
public class TestType
{
    [Nest.String(Store = true, Index = FieldIndexOption.Analyzed )]
    public string  Text { get; set; }

    [Nested(IncludeInAll = true)]
    public List<NestedTestType> Nests { get; set; } = new List<NestedTestType>();

    public string Id { get; set; }
}

[ElasticsearchType]
public class NestedTestType
{
    [Nest.String(Store = true, Index = FieldIndexOption.Analyzed)]
    public string Value { get; set; }

    [Nest.String(Store = false)]
    public string NotStoredValue { get; set; }
}

在功能上是
            var connectionPool = new Elasticsearch.Net.SniffingConnectionPool(poolUris);
        var settings = new ConnectionSettings(connectionPool);
        client = new ElasticClient(settings);

        string testIndexName = "test";
        var createIndeReponse = client.CreateIndex(testIndexName);
        var mappingResponse = client.Map<TestType>(m => m.Index(testIndexName).AutoMap());
       mappingResponse = client.Map<NestedTestType>(m => m.Index(testIndexName).AutoMap());

        TestType testData = new TestType() { Text = "Hello world" };
        testData.Nests.Add( new NestedTestType() { Value = "In the list", NotStoredValue = "Not stored"} );

        IndexRequest<TestType> indexRequest = new IndexRequest<TestType>(testIndexName, "test_type");
        indexRequest.Document = testData;
        IIndexResponse iir = client.Index(indexRequest);

但是,最后一行的iir包含错误“无法将对象映射[嵌套]从嵌套更改为非嵌套”

我的问题是:

做索引的正确方法是什么?
在哪里可以找到对我有帮助的文档?

最佳答案

一些观察:

  • 可以从CLR类型名称中推断出TestTypeNestedTestType的类型名称。默认情况下,这些将是类型名称分别为testTypenestedTestType的驼峰式版本。
  • 由于NestedTestTypeTestType上的一个嵌套类型,因此您无需在索引中为其单独添加映射。 NestedTestType的映射是TestType的映射的一部分
  • 您没有为IdTestType指定值; NEST will infer the id of the document from the Id property将为空; Elasticsearch会很好用,并为文档生成一个唯一的id,并将其存储在_id字段中,但是不会针对Id中的_source属性设置此唯一的id,这意味着没有简单的方法可以使用id来检索此文档NEST约定。我建议为Id设置一个值,并将该字段映射为not_analyzed

  • 错误的原因是,在为TestType编制索引时,您将类型名称指定为test_type,而不是显式指定testType或仅让NEST为您推断它。

    当Elasticsearch看到json文档进来时,它没有将它与之前创建的TestType的映射相关联,因为类型名称不匹配(testTypetest_type),因此尝试将nests映射为一个对象。 但是,索引的确包含已经为路径nests下的对象嵌套的映射,这会引起错误。

    解决,我们可以做
    var connectionPool = new Elasticsearch.Net.SniffingConnectionPool(poolUris);
    string testIndexName = "test";
    
    var settings = new ConnectionSettings(connectionPool)
        // specify test to be the default index, meaning if no index name
        // is explicitly passed to a request or inferred from the type,
        // this will be the default
        .DefaultIndex(testIndexName);
    
    var client = new ElasticClient(settings);
    
    // create the index and add the mapping at the same time
    var createIndeReponse = client.CreateIndex(testIndexName, c => c
        .Mappings(m => m
            .Map<TestType>(mm => mm.AutoMap())
        )
    );
    
    TestType testData = new TestType { Text = "Hello world", Id = "1" };
    testData.Nests.Add(new NestedTestType { Value = "In the list", NotStoredValue = "Not stored" });
    
    IIndexResponse iir = client.Index(testData);
    

    如果要指定TestType应该映射为类型名称test_type,则可以在连接设置上使用MapDefaultTypeNames
    var settings = new ConnectionSettings(connectionPool)
        .DefaultIndex(testIndexName)
        .MapDefaultTypeNames(d => d
            .Add(typeof(TestType), "test_type")
        );
    

    10-07 13:30