Skip to content

Aggregation Metadata does not handle object values properly #3072

@russcam

Description

@russcam

The loop to read aggregation metadata

while (reader.TokenType != JsonToken.EndObject)
{
var key = (string) reader.Value;
reader.Read();
var value = reader.Value;
meta.Add(key, value);
reader.Read();
}

does not handle the scenario where the metadata value is an object. In this case, the reader can end up reading the property names of a metadata value object, and adding them as keys within the dictionary e.g.

var response = client.Search<User>(s => s
	.Size(0)
	.Query(q => +q
		.Term(m => m
			.Field(f => f.Badges.First().Name)
            .Value("c#")
        )
    )
	.Aggregations(a => a
		.SignificantTerms("badges", st => st
			.Field(f => f.Badges.First().Name)
            .Meta(m => m
                .Add("meta_1", "value_1")
                .Add("meta_2", 2)
                .Add("meta_3", new { meta_3 = "value_3" })
            )
		)
	)
);

results in the following exception:

System.ArgumentException: An item with the same key has already been added.   at 
System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)   at 
Nest.AggregateJsonConverter.GetMetadata(JsonReader reader)   at
Nest.AggregateJsonConverter.ReadAggregate(JsonReader reader, JsonSerializer serializer)   at 
Nest.AggregateDictionaryConverter.ParseAggregate(JsonReader reader, JsonSerializer serializer, String name, Dictionary`2 dictionary)   at Nest.AggregateDictionaryConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)   at 
Nest.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)   at 
Nest.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)   at 
Nest.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)   at 
Nest.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)   at 
Nest.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)   at Nest.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)   at Nest.InternalSerializer.Deserialize(Type type, Stream stream)   at 
Nest.InternalSerializer.Deserialize[T](Stream stream)   at 
Elasticsearch.Net.ResponseBuilder.SetBody[TResponse](ApiCallDetails details, RequestData requestData, Stream responseStream, String mimeType) in T:\TeamCity\buildAgent\work\38a00213fd0f22c3\src\Elasticsearch.Net\Transport\Pipeline\ResponseBuilder.cs:line 100   at Elasticsearch.Net.ResponseBuilder.ToResponse[TResponse](RequestData requestData, Exception ex, Nullable`1 statusCode, IEnumerable`1 warnings, Stream responseStream, String mimeType) in T:\TeamCity\buildAgent\work\38a00213fd0f22c3\src\Elasticsearch.Net\Transport\Pipeline\ResponseBuilder.cs:line 25   at Elasticsearch.Net.HttpConnection.Request[TResponse](RequestData requestData) in T:\TeamCity\buildAgent\work\38a00213fd0f22c3\src\Elasticsearch.Net\Connection\HttpConnection.cs:line 180   at Elasticsearch.Net.RequestPipeline.CallElasticsearch[TResponse](RequestData requestData) in T:\TeamCity\buildAgent\work\38a00213fd0f22c3\src\Elasticsearch.Net\Transport\Pipeline\RequestPipeline.cs:line 451   at Elasticsearch.Net.Transport`1.Request[TResponse](HttpMethod method, String path, PostData data, IRequestParameters requestParameters) in T:\TeamCity\buildAgent\work\38a00213fd0f22c3\src\Elasticsearch.Net\Transport\Transport.cs:line 68

because the meta_3 property on the metadata item with key meta_3 is read and is attempted to be added to the meta dictionary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions