Search code examples
.netelasticsearch

How to create index mapping in Elastic.Clients.Elasticsearch for .Net


I'm using version 8 of the .NET 'Elastic.Clients.Elasticsearch' nuget package and trying to create an index mapping based on the below model. How do I map the Employee members and their JobRole members? I tried using "Object" and "Nested", without luck.

Furthermore how do I exclude properties from being indexed? Attribute mappings like:

[Text(Name = "last_name")]

... are no longer supported in version 8. The only option is "fluent mapping".

Unfortunately there's only documentation available for version 7, https://www.elastic.co/guide/en/elasticsearch/client/net-api/7.17/fluent-mapping.html

public class Company
{
    public string CompanyName { get; set; }
    public Employee EmployeeInfo { get; set; }
}


public class Employee
{
    public string EmployeeName { get; set; }
    public JobRole[] JobRoles { get; set; }
}


public class JobRole
{
    public string RoleName { get; set; }
}

This is my code and as you can see I got lost halfway..

var createIndexResponse = client.Indices.Create<Company>("myindex", c => c
            .Mappings(m => m
                .Properties(p => p
                    .Keyword(s => s.CompanyName)
                 .Object<Employee> (x=>x.EmployeeInfo.EmployeeName  // Got lost here...
                )
            )
        );

Anyone?


Solution

  • When creating new Properties, the IProperty it requests are the property types you'd assign to a field. Like TextProperty, ObjectProperty, NestedProperty, LongProperty:

        var response = await _client.Indices.CreateAsync<Company>("myindex", c => c
            .Mappings(map => map
                .Properties(p => p
                .Text(t => t.CompanyName)
                .Object(o => o.EmployeeInfo, objConfig => objConfig
                    .Properties(p => p
                        .Text(t => t.EmployeeInfo.EmployeeName)
                        .Object(n => n.EmployeeInfo.JobRoles, objConfig => objConfig
                            .Properties(p => p
                                .Text(t => t.EmployeeInfo.JobRoles.First().RoleName)
                            )
                        )
                    )
                )
            )
        ));
    

    ObjectProperty jobRolesProperty = new ();
        jobRolesProperty.Properties.Add("roleName", new TextProperty());
    
        var response = await _client.Indices.CreateAsync<Company>("myindex", c => c
            .Mappings(map => map
                .Properties(
                    new Properties<Company>()
                    {
                        { "companyName", new TextProperty() },
                        { "employeeInfo", new ObjectProperty()
                        {
                                Properties = new Properties<Employee>()
                                {
                                    { "employeeName", new TextProperty() },
                                    { "jobRoles", jobRolesProperty }
                                }
                            }
                        }
                    }
                )
            )
        );
    

     //Another syntax usage
    ObjectProperty jobRolesProperty = new ();
        jobRolesProperty.Properties.Add("roleName", new TextProperty());
    
            var response = await _client.Indices.CreateAsync<Company>("myindex", c => c
            .Mappings(map => map
                .Properties(p => p
                .Text(t => t.CompanyName)
                .Object(o => o.EmployeeInfo, objConfig => objConfig
                    .Properties(
                                new Properties<Employee>()
                                {
                                    { "employeeName", new TextProperty() },
                                    { "jobRoles", jobRolesProperty }
                                }
                    )
                )
            )
        ));
    

    The mapping created:

    {
    "mappings": {
        "properties": {
            "companyName": {
                "type": "text"
            },
            "employeeInfo": {
                "properties": {
                    "employeeName": {
                        "type": "text"
                    },
                    "jobRoles": {
                        "properties": {
                            "roleName": {
                                "type": "text"
                            }
                        },
                        "type": "object"
                    }
                },
                "type": "object"
            }
        }
    }
    

    }

    For managing settings you can check this answer: Elastic Search 8 Defining Analyzers