I'm upgrading my Elasticsearch project from v6.6 to v7.6.2. I use Elasticsearch.NET and NEST in order to create my index including mappings, settings, and to ingest my data into Elasticsearch from my SQL db.
Everything works well in v6.6, but when I upgraded to v7.6.2, it no longer accepts my custom mappings and settings. I'm referring to things like my nested objects, my custom analyzers, etc. The data does get ingested, but it defaults to the, well, default mapping (where mostly everything is a keyword or simple data type).
This type of behavior normally happens when there's something syntactically wrong in your mappings or in your POCO. This isn't my case, I don't think.
Is there some breaking change in v7.x that I may have missed? I've been through the documentation fairly extensively.
To give an example of what my mapping should look like, here's an excerpt (from my v6.6 cluster).
...notice things like the 'products' object is of type: nested...
[{"searchdata":{"_all":{"enabled":false},"properties":{"groupid":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"products":{"type":"nested","properties":{"adddate":{"type":"date"},"additionaltitles":{"type":"text"},"additionaltitleslist":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"adult":{"type":"integer"},"artists":{"properties":{"id":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"name":{"type":"text","norms":false,"fields":{"ci":{"type":"text","norms":false,"analyzer":"caseInsensitive"},"nc":{"type":"text","norms":false,"analyzer":"titleNoCharAnalyzer"},"raw":
and here's what it shows as the default version in v7.6.2...
...notice things like the 'products' object not nested, and lots of 'keyword' types, no custom analyzers, etc. ...
[{"_doc":{"properties":{"groupid":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"products":{"properties":{"adult":{"type":"long"},"artists":{"properties":{"id":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"name":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"nameidsplit":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"nameremarticle":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}},"catalognum":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"costprice":{"type":"float"},"cover":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"credits":{"properties":{"id":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"name":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"nameidsplit":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"nameremarticle":{"type":"text","fields":
As you may be able to notice, the v6.6 version is much more detailed and contains my nested objects, etc. But my v7.6.2 version contains the basic, default structure.
Something must be going wrong here but I don't know what.
Is there some debug logging level that I can enable that will tell me why it's "failing"?
UPDATE So I'm putting a slightly abbreviated version of how I'm mapping my objects and settings here. Hopefully this helps to understand this issue.
var indexCreate = client.Indices.Create(indexName, nc => nc
.Settings(st => st
.RefreshInterval(60) //slowing the refresh interval so we can get a running count
.NumberOfReplicas(0) //must be set to refresh after created
.NumberOfShards(numOfShards)
.Analysis(a => a
.Analyzers(an => an
.UserDefined("fullTermCaseInsensitive", FullTermCaseInsensitive)
.UserDefined("fullTerm", FullTerm)
.UserDefined("caseInsensitive", CaseInsensitive)
)
.TokenFilters(tf => tf
.UserDefined("syn", Syn)
.UserDefined("myStopFilter", MyStopFilter)
.UserDefined("wordDelimiter", WordDelimiter)
)
)
)
.Map<Store24>(m => m
.Dynamic(false)
.AutoMap()
.Properties(props =>
{
SetPutMappingStore24(props); //see function below
return props;
})
));
private static void SetPutMappingStore24(PropertiesDescriptor<Store24> pm)
{
pm.Nested<Product>(x => x
.AutoMap()
.Name(nm => nm.Products)
.Properties(pr => pr
.Nested<StorePriceSplit>(sp => sp
.Name("storeprice").AutoMap()
)
.Properties(props =>
{
SetPutMappingDescriptorTiWo(props, "tracks");
SetPutMappingDescriptorTiWo(props, "title");
}
)
);
//...... more fluent mappings here
}
[ElasticsearchType(IdProperty = "Groupid")]
public class Store24
{
/// <summary>
/// Identifiers
/// </summary>
[Key]
[Keyword]
public string Groupid { get; set; }
[JsonIgnore]
public string Upc { get; set; }
[JsonIgnore]
public string Titleremarticle { get; set; }
[Nested]
[PropertyName("products")]
public IEnumerable<Product> Products { get; set; }
//... more properties here
}
[ElasticsearchType(RelationName = "product")]
public class Product
{
[Key]
[Text(Analyzer = "fullTermCaseInsensitive")]
public string Upc { get; set; }
[Text(Analyzer = "fullTermCaseInsensitive", Fielddata = true)]
public string Titleremarticle { get; set; }
//...more properties here
}
I use two objects, one called Store24 which maps from the data returned from SQL and one called Product which creates the Elasticsearch mapping.
I figured out my own issue. It seems the creating of the index was throwing an error but I wasn't seeing it. It was being 'hidden' by the response to the Indices.Create() returned object. (the var indexCreate object in my sample above). Once I poked at it, the following error was being thrown: "Token filter [wordDelimiter] cannot be used to parse synonyms".
This was an issue in my settings - I guess a breaking change for 7.x that I didn't see. A rather complex issue actually.