Type and Relation names inference

edit

Type names are resolved in NEST by default, by lowercasing the CLR type name

var settings = new ConnectionSettings();
var resolver = new TypeNameResolver(settings);
var type = resolver.Resolve<Project>();
type.Should().Be("project");

Applying a type name with ElasticsearchTypeAttribute

edit

A type name can be applied for a CLR type, using the Name property on ElasticsearchTypeAttribute

[ElasticsearchType(Name = "attributed_project")]
public class AttributedProject { }

var settings = new ConnectionSettings();
var resolver = new TypeNameResolver(settings);
var type = resolver.Resolve<AttributedProject>();
type.Should().Be("attributed_project");

Applying a type name with DataContractAttribute

edit

Similarly to ElasticsearchTypeAttribute, a type name can be applied for a CLR type, using the Name property on System.Runtime.Serialization.DataContractAttribute

[DataContract(Name = "data_contract_project")]
public class DataContractProject { }

var settings = new ConnectionSettings();
var resolver = new TypeNameResolver(settings);
var type = resolver.Resolve<DataContractProject>();
type.Should().Be("data_contract_project");

Default type name

edit

With Elasticsearch 6.x, you can only have a single type per index and in the long run types will be phased out entirely. The need to tag types is no longer necessary, so in many cases it makes sense to use a single fixed type, like doc

var settings = new ConnectionSettings().DefaultTypeName("doc");
var resolver = new TypeNameResolver(settings);
var type = resolver.Resolve<Project>();
type.Should().Be("doc");

With such a setting in place, all CLR types will resolve to doc as the type name to use in Elasticsearch.

Override type name inferrer

edit

You can provide a delegate to override the default type name inferrer for types

var settings = new ConnectionSettings()
    .DefaultTypeNameInferrer(t=>t.Name.ToLower() + "-suffix");
var resolver = new TypeNameResolver(settings);
var type = resolver.Resolve<Project>();
type.Should().Be("project-suffix");

Relation names

edit

Prior to Elasticsearch 6.x you could have multiple types per index. They acted as a discrimatory column but were often confused with tables. The fact that the mapping API’s treated them as seperate entities did not help.

The general guideline has always been to use a single type per index. Starting from 6.x this is also enforced. Some features still need to store multiple types in a single index such as Parent/Child join relations.

Both Parent and Child will need to have resolve to the same typename to be indexed into the same index.

Therefore in 6.x we need a different type that translates a CLR type to a join relation. This can be configured seperately using .RelationName()

var settings = new ConnectionSettings()
    .DefaultMappingFor<CommitActivity>(m => m
        .IndexName("projects-and-commits")
        .TypeName("doc")
        .RelationName("commits")
    )
    .DefaultMappingFor<Project>(m => m
        .IndexName("projects-and-commits")
        .TypeName("doc")
        .RelationName("projects")
    );

var resolver = new RelationNameResolver(settings);
var relation = resolver.Resolve<Project>();
relation.Should().Be("projects");

relation = resolver.Resolve<CommitActivity>();
relation.Should().Be("commits");

RelationName uses the DefaultTypeNameInferrer to translate CLR types to a string representation.

Explicit TypeName configuration does not affect how the default relation for the CLR type is represented though

var settings = new ConnectionSettings()
    .DefaultMappingFor<Project>(m => m
        .IndexName("projects-and-commits")
        .TypeName("doc")
    );

var resolver = new RelationNameResolver(settings);
var relation = resolver.Resolve<Project>();
relation.Should().Be("project");