I'm having an issue that I haven't seen on here yet. I am using the .net NEST client.
I have multiple classes (ProductError and BatchError) with the same nested property (Error). When I save these documents individually into an empty/newly-created index, they are mapped correctly. I have done this in unit tests multiple times.
When I index these documents in my web app, both ProductError and BatchError need to be saved to the same index. When I have BatchErrors saved in the index already, I cannot save any Product Errors. I am able to create the Product Error correctly and the Error property is correctly nested (I can view it in the Visual Studio 2017 debugger to check, it's also been unit tested appropriately).
However, I get an error when I try to save the ProductError to the same index that currently has BatchErrors already saved to it.
I haven't been able to figure out why. The exceptions says "object mapping [errors] can't be changed from nested to non-nested", but I know that is not correct because I can construct the document properly, it just won't save to the index.
Also, a potentially important part of information is that if I save a ProductError in the index first, then the same thing happens when I try to save a BatchError.
I'll gladly provide anymore information. Let me know if you need something. I appreciate the help and have been stuck on this for a long time.
Full Error Text
Invalid NEST response built from a unsuccessful low level call on PUT: /unit_test_errors_save/producterror/unittest7
# Audit trail of this API call:
- [1] BadResponse: Node: / Took: 00:00:00.1160897
# ServerError: ServerError: 400Type: illegal_argument_exception Reason: "object mapping [errors] can't be changed from nested to non-nested"
# OriginalException: System.Net.WebException: The remote server returned an error: (400) Bad Request.
at System.Net.HttpWebRequest.GetResponse()
at Elasticsearch.Net.HttpConnection.Request[TReturn](RequestData requestData)
# Request:
<Request stream not captured or already read to completion by serializer. Set DisableDirectStreaming() on ConnectionSettings to force it to be set on the response.>
# Response:
<Response stream not captured or already read to completion by serializer. Set DisableDirectStreaming() on ConnectionSettings to force it to be set on the response.>
CLASSES
namespace Ilab.Elasticsearch.V5FeedErrors.FeedErrors
{
[JsonObjectAttribute]
public class Error
{
public string Identifier { get; set; }
public string ErrorMessage { get; set; }
}
}
namespace Ilab.Elasticsearch.V5FeedErrors.FeedErrors
{
[ElasticsearchType]
public class BatchError : BaseElasticsearchStorableError, IHasMsku
{
[Number]
public long BatchId { get; set; }
[String(Analyzer = "ilab_partial_word_analyzer")]
public string BatchName { get; set; }
[Nested]
public Error[] Errors { get; set; }
[String(Analyzer = "ilab_partial_word_analyzer")]
public List<string> Mskus { get; set; }
public BatchError()
{
}
public BatchError(long userId, string submissionId, Guid correlationId, DateTime timestamp, long batchId, string batchName, Dictionary<string, string> errors, List<string> mskus)
: base(userId, submissionId, correlationId, timestamp)
{
BatchId = batchId;
BatchName = batchName;
Mskus = mskus;
var errorList = new List<Error>();
if (errors != null)
{
foreach (var error in errors)
{
errorList.Add(new Error() { Identifier = checkIfNull(error.Key), ErrorMessage = checkIfNull(error.Value) });
}
this.Errors = errorList.ToArray();
}
else
{
errorList.Add(new Error() { Identifier = "-", ErrorMessage = "-" });
this.Errors = errorList.ToArray();
}
}
private string checkIfNull(string e)
{
if (string.IsNullOrEmpty(e))
{
return "-";
}
else
{
return e;
}
}
}
}
namespace Ilab.Elasticsearch.V5FeedErrors.FeedErrors
{
[ElasticsearchType]
public class ProductError : BaseElasticsearchStorableError, IHasMsku
{
public long BatchId { get; set; }
[String(Analyzer = "ilab_partial_word_analyzer")]
public string BatchName { get; set; }
[String(Analyzer = "ilab_partial_word_analyzer")]
public string Asin { get; set; }
[String(Analyzer = "ilab_partial_word_analyzer")]
public string Fnsku { get; set; }
[Nested]
public Error[] Errors { get; set; }
[String(Analyzer = "ilab_partial_word_analyzer")]
public List<string> Mskus { get; set; }
public ProductError()
{
}
public ProductError(long userId, string submissionId, Guid correlationId, DateTime? timestamp, long batchId, string batchName, string asin, string msku, string fnsku, Dictionary<string, string> errors = null)
: base(userId, submissionId, correlationId, timestamp)
{
BatchId = batchId;
BatchName = batchName;
Asin = asin;
Mskus = new List<string>() { msku };
Fnsku = fnsku;
var errorList = new List<Error>();
if (errors != null)
{
foreach (var error in errors)
{
errorList.Add(new Error() { Identifier = checkIfNull(error.Key), ErrorMessage = checkIfNull(error.Value) });
}
this.Errors = errorList.ToArray();
}
else
{
errorList.Add(new Error() { Identifier = "-", ErrorMessage = "-" });
this.Errors = errorList.ToArray();
}
}
private string checkIfNull(string e)
{
if (string.IsNullOrEmpty(e))
{
return "-";
}
else
{
return e;
}
}
}
}