Search code examples
c#.netelasticsearchmappingnest

ElasticSearch - Whitespace analyzer for Dictionary<object, object>


I'm trying to change a analyzer for an index's mapping. I understand how to do it for a simple Text type property but in .NET the class that I create the mapping from (using NEST's AutoMap() function), is of type Dictionary<object, object> which creates the index mapping that looks like this:

"attributes": {
  "properties": {
    "comparer": {
      "type": "object"
    },
    "count": {
      "type": "integer"
    },
    "item": {
      "type": "object"
    },
    "keys": {
      "properties": {
        "count": {
          "type": "integer"
        }
      }
    },
    "values": {
      "properties": {
        "count": {
          "type": "integer"
        }
      }
    }
  }
},

When trying to change the analyzer for one of the fields inside the above mapping I'm getting the following message:

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "mapper [attributes.Title] of different type, current_type [text], merged_type [ObjectMapper]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "mapper [attributes.Title] of different type, current_type [text], merged_type [ObjectMapper]"
  },
  "status": 400
}

I'm assuming from the error message that I cannot put a analyzer on something as generic as a Dictionary<object, object> but I need to find a approach that could work? (assuming it is possible)


Solution

  • The following NEST auto & manual fluent code solved the above problem for me. I believe there was an issue with Elastic Search trying to understand Dictionary<object, object> that caused it to never create the index. Using Object<object> did the trick:

    elasticClient.CreateIndex("YOURINDEX", i => i
        .Mappings(ms => ms
            .Map<YOURTYPE>(m => m
                .AutoMap()
                .Properties(props => props
                    .Object<object>(o => o
                        .Name(x => x.Attributes)
                        .Properties(pprops => pprops
                            .Text(ps => ps
                                .Name(AttributeType.Title.ToString().ToLower())
                                .Analyzer("whitespace")
                                .Fielddata(true)
                                .Fields(f => f
                                    .Keyword(k => k
                                        .Name("keyword")
                                    )
                                )
                            )
                        )
                    )
                )
            )
        )
    );