简体   繁体   English

Elasticsearch Nest 2.x索引嵌套对象

[英]Elasticsearch Nest 2.x index nested object

I'm new in Elasticsearch and Nest and blocked in a problem. 我是Elasticsearch和Nest的新手,遇到了问题。 What I want to do is create a index and index a doc with nested fields. 我想要做的是创建索引并使用嵌套字段索引doc。

    [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; }
}

and in the function it is 它在功能中

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

However, the iir in the last line contains an error "object mapping [nests] can't be changed from nested to non-nested" 但是,最后一行中的iir包含错误“对象映射[嵌套]无法从嵌套更改为非嵌套”

My questions are : 我的问题是:

What is the correct way to do the indexing? 索引的正确方法是什么? Where can I find documentation which will help me further? 我在哪里可以找到有助于我进一步帮助的文档?

A few observations: 一些观察:

  • The type names for both TestType and NestedTestType will be inferred from the CLR type name. TestTypeNestedTestType的类型名称将从CLR类型名称推断出来。 By default, these will be the camel cased version of the type name ie testType and nestedTestType , respectively. 默认情况下,这些将是类型名称的驼峰式版本,即testTypenestedTestType

  • Since NestedTestType is a nested type on TestType , you don't need to add a mapping separately for it in the index; 由于NestedTestTypeNestedTestType上的嵌套类型, TestType您无需在索引中为其单独添加映射; the mapping of NestedTestType is part of the mapping of TestType NestedTestType的映射是TestType映射的TestType

  • You don't specify a value for the Id of TestType ; 您没有为TestTypeId指定值; NEST will infer the id of the document from the Id property which will be null; NEST将从Id属性推断文档的id,该属性为null; Elasticsearch will be fine with this and generate a unique id for the document, storing it in the _id field, but this unique id will not be set against the Id property in _source meaning there would be no easy way of retrieving this document by id using NEST conventions. Elasticsearch对此很好,并为文档生成一个唯一的id,将其存储在_id字段中,但是这个唯一的id不会针对_source中的Id属性设置,这意味着没有简单的方法可以通过id使用id检索这个文档NEST惯例。 I'd recommend setting a value for Id and also mapping the field as not_analyzed 我建议为Id设置一个值,并将字段映射为not_analyzed

The reason for the error is that when indexing TestType , you specify the type name to be test_type as opposed to explicitly specifying testType or just letting NEST infer it for you. 出错的原因是,在索引TestType ,您将类型名称指定为test_type ,而不是显式指定testType或只是让NEST为您推断它。

When Elasticsearch sees the json document coming in, it doesn't associate it with the mapping for TestType that was created earlier since the type names don't match ( testType vs. test_type ) so attempts to map nests as an object. 当Elasticsearch看到json文档进入时,它不会将它与之前创建的TestType的映射TestType ,因为类型名称不匹配( testTypetest_type ),因此尝试将nests映射为对象。 But , the index does contain a nested mapping already for objects under the path nests , which is giving rise to the error. 但是 ,索引确实包含已经存在于路径nests下的对象的嵌套映射,这会引起错误。

To solve, we can do 要解决,我们可以做到

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

If you want to specify that TestType should be mapped as the type name test_type , you can use MapDefaultTypeNames on connection settings 如果要指定TestType应映射为类型名称test_type ,则可以在连接设置上使用MapDefaultTypeNames

var settings = new ConnectionSettings(connectionPool)
    .DefaultIndex(testIndexName)
    .MapDefaultTypeNames(d => d
        .Add(typeof(TestType), "test_type")
    );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM