1
votes

I want to use the copy_to functionality with Nest. I've read that I need to use the fluent mapping (Elasticsearch Nest and CopyTo).

Is it possible to use the attribute based mapping then fluent mapping on top of that to add copy_to? If so, are there any examples? I'm having difficulty finding the answer.

The field I want to copy to does not exist in my model class. I just want to search on it in elasticsearch.

[ElasticType(IdProperty = "CustomerId", Name = "customer_search")]
public class CustomerSearchResult : BindableBase
{
    [ElasticProperty(Name = "customer_id", Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String)]
    public int CustomerId { get; set; }
    [ElasticProperty(Name = "account_type", Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String)]
    public string AccountType { get; set; }
    [ElasticProperty(Name = "short_name", Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String)]
    public string ShortName { get; set; }
    [ElasticProperty(Name = "legacy_name", Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String)]
    public string LegacyName { get; set; }
    [ElasticProperty(Name = "legacy_contact_name", Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String)]
    public string LegacyContactName { get; set; }
    [ElasticProperty(Name = "city", Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String)]
    public string City { get; set; }
    [ElasticProperty(Name = "state_abbreviation", Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String)]
    public string StateAbbreviation { get; set; }
    [ElasticProperty(Name = "country", Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String)]
    public string Country { get; set; }
    [ElasticProperty(Name = "postal_code", Index = FieldIndexOption.NotAnalyzed, Type = FieldType.String)]
    public string PostalCode { get; set; }
}

In the above class I want to use ShortName, LegacyName, and LegacyContactName and copy_to a field called "search" which will be an analyzed field.

1

1 Answers

4
votes

Something like the following should do it

void Main()
{
    var settings = new ConnectionSettings(new Uri("http://localhost:9200"));
    var connection = new InMemoryConnection(settings);
    var client = new ElasticClient(connection: connection);


    var indexResponse = client.CreateIndex("customer_searches", c => c
        .AddMapping<CustomerSearchResult>(m => m
            .MapFromAttributes()
            .Properties(p => p
                .String(s => s.Name("short_name").CopyTo("search").Index(FieldIndexOption.NotAnalyzed))
                .String(s => s.Name("legacy_name").CopyTo("search").Index(FieldIndexOption.NotAnalyzed))
                .String(s => s.Name("legacy_contact_name").CopyTo("search").Index(FieldIndexOption.NotAnalyzed))
                .String(s => s.Name("search").Index(FieldIndexOption.Analyzed))
            )
        )
    );

    Console.WriteLine(Encoding.UTF8.GetString(indexResponse.RequestInformation.Request));
}

Which outputs

{
  "settings": {
    "index": {}
  },
  "mappings": {
    "customer_search": {
      "properties": {
        "customer_id": {
          "index": "not_analyzed",
          "type": "string"
        },
        "account_type": {
          "index": "not_analyzed",
          "type": "string"
        },
        "short_name": {
          "index": "not_analyzed",
          "copy_to": [
            "search"
          ],
          "type": "string"
        },
        "legacy_name": {
          "index": "not_analyzed",
          "copy_to": [
            "search"
          ],
          "type": "string"
        },
        "legacy_contact_name": {
          "index": "not_analyzed",
          "copy_to": [
            "search"
          ],
          "type": "string"
        },
        "city": {
          "index": "not_analyzed",
          "type": "string"
        },
        "state_abbreviation": {
          "index": "not_analyzed",
          "type": "string"
        },
        "country": {
          "index": "not_analyzed",
          "type": "string"
        },
        "postal_code": {
          "index": "not_analyzed",
          "type": "string"
        },
        "search": {
          "index": "analyzed",
          "type": "string"
        }
      }
    }
  }
}

The call to Properties() overrides the default conventions and attribute mappings so you need to specify that the fields are not_analyzed there as well.