0

I've created an application in MVC5/EF6, DB first that indexes some date into elasticsearch.

Example:

public static ElasticClient ElasticClient
        {
            get
            {
                Uri uri = new Uri("http://localhost:9200");
                var setting = new ConnectionSettings(uri, "crude");
                setting.SetJsonSerializerSettingsModifier(x =>
                {
                    x.ContractResolver = new CustomContractResolver();
                    x.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                    x.PreserveReferencesHandling = PreserveReferencesHandling.All;
                    x.NullValueHandling = NullValueHandling.Ignore;
                    x.Formatting = Formatting.None;

                });
                return new ElasticClient(setting);
            }
        }

ElasticClient.IndexMany<Customer>(db.Customer.Where(x => x.Active == true).ToList());  

ElasticClient.IndexMany<CustomerContract>(db.CustomerContract.Where(a => a.Active == true).ToList());

I've written a custom contract resolver so he doesn't index all nested types, it basically discards any IOCollections:

using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace CMDBv2.Helpers
{
    public class CustomContractResolver : DefaultContractResolver 
    {
        protected override JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
        {
            JsonProperty prop = base.CreateProperty(member, memberSerialization);

            if (prop.PropertyType.ToString().ToLower().Contains("icollection"))
            {
                prop.ShouldSerialize = obj => false;
            }

            return prop;
        }
    }
}

What I saw was, that after indexing, the $id is always 1:

ElasticHQ Result

This is giving me issues when I search:

 ElasticSearchClient.Search<CustomerContract>(body => body.AllIndices().Size(500).Query(query => query.Bool(b => b.Must(m => m.QueryString(qs => qs.Query("MyQRY")))))).Documents.ToList();

Exception:

A different value already has the Id '1'

Stacktrace:

at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.AddReference(JsonReader reader, String id, Object value)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Populate(JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerProxy.PopulateInternal(JsonReader reader, Object target)
   at Newtonsoft.Json.JsonSerializer.Populate(JsonReader reader, Object target)
   at Nest.ConcreteTypeConverter`1.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer) in C:\code\elasticsearch-net\src\Nest\Resolvers\Converters\ConcreteTypeConverter.cs:line 90
   at Nest.DefaultHitConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer) in C:\code\elasticsearch-net\src\Nest\Resolvers\Converters\ConcreteTypeConverter.cs:line 36
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id)

The strange part is that he recognises the ID good for the ID. I also don't understand why he would create a $id field in the mapping:

enter image description here

So, how can I tell NEST to A) not create $id, or B) to give it a proper value?

Bart De Vos
  • 571
  • 2
  • 7
  • 23
  • Looks like your question already answered here: how to remove $id during JSON serialization: http://stackoverflow.com/questions/11542144/how-to-remove-id-during-json-serialization – Tomas Kirda Feb 16 '15 at 02:14
  • It appears that the custom ContractResolver setting overrides the PreserveReferencesHandling setting. Please refer here: http://stackoverflow.com/questions/18128689/json-net-adding-id-to-ef-objects-despite-setting-preservereferenceshandling-to – Manolis Feb 17 '15 at 08:47

0 Answers0