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

1

12

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?

Fancher answered 25/3, 2023 at 14:58 Comment(4)
Just wanted to +1 your question. I'm in the same boat - did you make any progress?Arlana
@Arlana No I didn't. Very disappointing! I installed version 7.Fancher
I did some reading up and it appears that its not GA yet so it's best to use v7 whilst the full api is being developedArlana
Attribute Mappings won't be implemented in v8, you have to use Fluent API. elastic.co/guide/en/elasticsearch/client/net-api/8.9/…Coaptation
I
9

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

Impossibly answered 31/7, 2023 at 2:11 Comment(4)
Sounds great, but how is this an improvement compared to previous versions?Fancher
I can't comment as to the rationale in changing the library. This was the result of two weeks of implementation and banging my head against the wall until I smashed the correct buttons. Documentation would have been nice, but F12 on classes and reading the github repo ended up providing a solution.Impossibly
Well, I think having fewer options to achieve the same thing in a library makes sense since this is more maintainable. But Elasticsearch should have provided such an answer as this one in their docs.Coaptation
Thank you for this answer. Totally helped me out!Elmoelmore

© 2022 - 2024 — McMap. All rights reserved.