Daniel Medina
Daniel Medina

Reputation: 947

Nest mapping the same type twice

I'm in trouble with Nest. I have a brand new index on Elasticsearch 5.1.1 and I'm trying to define a type mapping by dotnet core.

My classes look like that:

public class Review
{
    public Guid Id { get; set; }
    public User User { get; set; }
    public Movie Movie { get; set; }
    public int Grade { get; set; }
    public string Title { get; set; }
    public string Comment { get; set; }
    public bool HasSpoiler { get; set; }
    public bool BoughtInIngresso { get; set; }
    public ReviewStatus Status { get; set; }
    public DateTime Date { get; set; }
}

public class User
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }


public class Movie
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }

In my application, I'm trying to define a short form of the type mapping (just for test) like that:

var pool = new StaticConnectionPool(nodes);

    var settings = new ConnectionSettings(pool);
    settings.DefaultIndex(elasticSettings.IndexName);

    var client = new ElasticClient(settings);

    client.Map<Review>(m => 
        m.Index("my_index")
        .Type("reviews")
        .Properties(ps=>
            ps.Keyword(k=>
                    k.Name("title"))
            .Text(t=>
                    t.Name("comment"))
        )
    );

And the final result is this. Observe the reviews AND review mapping being created. I only want "reviews", not "review".

{
  "my_index": {
    "mappings": {
      "reviews": {
        "properties": {
          "comment": {
            "type": "text"
          },
          "title": {
            "type": "keyword"
          }
        }
      },
      "review": {
        "properties": {
          "boughtInSite": {
            "type": "boolean"
          },
          "comment": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "date": {
            "type": "date"
          },
          "grade": {
            "type": "long"
          },
          "hasSpoiler": {
            "type": "boolean"
          },
          "id": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "movie": {
            "properties": {
              "id": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "name": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          },
          "status": {
            "type": "long"
          },
          "title": {
            "type": "keyword"
          },
          "user": {
            "properties": {
              "id": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "name": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

What I'm doing wrong? This happen if I use AutoMap() too. I don't want to map with attributes because I want to preserve my POCO classes, but if was the only way, I can do.

Some help?

Upvotes: 0

Views: 488

Answers (1)

Russ Cam
Russ Cam

Reputation: 125498

You haven't shown how you are indexing Review types, but I suspect that you're not specifying the type as "reviews" when indexing; in this case, NEST will infer the type from the C# POCO type name.

NEST provides a way for the Elasticsearch type "reviews" to be associated with the C# POCO type Review using InferMappingFor<T>() on ConnectionSettings

public class Review
{
    public Guid Id { get; set; }
    public User User { get; set; }
    public Movie Movie { get; set; }
    public int Grade { get; set; }
    public string Title { get; set; }
    public string Comment { get; set; }
    public bool HasSpoiler { get; set; }
    public bool BoughtInIngresso { get; set; }
    public ReviewStatus Status { get; set; }
    public DateTime Date { get; set; }
}

public enum ReviewStatus
{
    Good,
    Bad,
    NotTooShabby
}

public class User
{
    public string Id { get; set; }
    public string Name { get; set; }
}


public class Movie
{
    public string Id { get; set; }
    public string Name { get; set; }
}

void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var defaultIndex = "default-index";
    var connectionSettings = new ConnectionSettings(pool)
        .InferMappingFor<Review>(m => m
            .TypeName("reviews")
        )
        .DefaultIndex(defaultIndex);

    var client = new ElasticClient(connectionSettings);

    client.CreateIndex("my_index", c => c
        .Mappings(m => m
            .Map<Review>(mm => mm
                .Properties(ps => ps
                    .Keyword(k => k
                        .Name(n => n.Title)
                    )
                    .Text(t => t
                        .Name(n => n.Comment)
                    )
                )
            )   
        )
    );
}

With this approach, you don't need to specify the type on every request now, although you can override it per request if you need to.

With AutoMap(), you can let NEST infer the Elasticsearch field types from the C# POCO property types, then use .Properties() to override any mappings you'd like.

Upvotes: 0

Related Questions