Skip to content

Commit 31a13d8

Browse files
committed
Add Analysis json serializing
1 parent f3a8340 commit 31a13d8

File tree

10 files changed

+491
-60
lines changed

10 files changed

+491
-60
lines changed

src/Nest.Tests.Integration/Indices/IndicesTests.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public void GetIndexSettingsComplex()
4646
settings.NumberOfReplicas = 4;
4747
settings.NumberOfShards = 8;
4848
settings.Analysis.Analyzers.Add("snowball", new SnowballAnalyzer { Language = "English" });
49+
settings.Analysis.Analyzers.Add("standard", new StandardAnalyzer { StopWords = new[]{"word1", "word2"}});
4950
var typeMapping = this._client.GetMapping(ElasticsearchConfiguration.DefaultIndex, "elasticsearchprojects");
5051
typeMapping.TypeNameMarker = index;
5152
settings.Mappings.Add(typeMapping);
@@ -61,6 +62,9 @@ public void GetIndexSettingsComplex()
6162
Assert.AreEqual(r.Settings.NumberOfShards, 8);
6263
Assert.Greater(r.Settings.Count(), 0);
6364
Assert.True(r.Settings.ContainsKey("merge.policy.merge_factor"));
65+
Assert.AreEqual(2, r.Settings.Analysis.Analyzers.Count);
66+
Assert.True(r.Settings.Analysis.Analyzers.ContainsKey("snowball"));
67+
Assert.True(r.Settings.Analysis.Analyzers.ContainsKey("standard"));
6468

6569
this._client.DeleteIndex(index);
6670
}

src/Nest/Domain/Analysis/Analyzers/AnalysisSettings.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
namespace Nest
66
{
7-
public class AnalysisSettings
7+
[JsonConverter(typeof(AnalysisSettingsConverter))]
8+
public class AnalysisSettings
89
{
910
public AnalysisSettings()
1011
{
@@ -14,16 +15,16 @@ public AnalysisSettings()
1415
this.CharFilters = new Dictionary<string, CharFilterBase>();
1516
}
1617

17-
[JsonConverter(typeof(DictionaryKeysAreNotPropertyNamesJsonConverter))]
18+
[JsonConverter(typeof(AnalyzerCollectionConverter))]
1819
public IDictionary<string, AnalyzerBase> Analyzers { get; set; }
1920

20-
[JsonConverter(typeof(DictionaryKeysAreNotPropertyNamesJsonConverter))]
21+
[JsonConverter(typeof(TokenFilterCollectionConverter))]
2122
public IDictionary<string, TokenFilterBase> TokenFilters { get; set; }
2223

23-
[JsonConverter(typeof(DictionaryKeysAreNotPropertyNamesJsonConverter))]
24+
[JsonConverter(typeof(TokenizerCollectionConverter))]
2425
public IDictionary<string, TokenizerBase> Tokenizers { get; set; }
2526

26-
[JsonConverter(typeof(DictionaryKeysAreNotPropertyNamesJsonConverter))]
27+
[JsonConverter(typeof(CharFilterCollectionConverter))]
2728
public IDictionary<string, CharFilterBase> CharFilters { get; set; }
2829
}
2930
}

src/Nest/ElasticClient-MappingIndex.cs

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Linq;
1+
using System;
2+
using System.ComponentModel;
3+
using System.Linq;
24
using Newtonsoft.Json;
35
using Newtonsoft.Json.Linq;
46
using System.Text.RegularExpressions;
@@ -33,21 +35,69 @@ public IIndexSettingsResponse GetIndexSettings(string index)
3335
{
3436
var o = JObject.Parse(status.Result);
3537
var settingsObject = o.First.First.First.First;
36-
var settings = new IndexSettings(); //this.Deserialize<IndexSettings>(settingsObject.ToString());
3738

39+
var settingsContainer = new JObject();
3840
foreach (JProperty s in settingsObject.Children<JProperty>())
3941
{
40-
settings.Add(StripIndex.Replace(s.Name, ""), s.Value.ToString());
42+
var name = StripIndex.Replace(s.Name, "");
43+
if (name.StartsWith("analysis"))
44+
{
45+
var key = name.Split('.');
46+
WriteJObject(settingsContainer, key, s.Value);
47+
}
48+
else
49+
{
50+
WriteJObject(settingsContainer, new[] { name }, s.Value);
51+
}
4152
}
4253

43-
44-
response.Settings = settings;
54+
response.Settings = this.Deserialize<IndexSettings>(settingsContainer);
4555
response.IsValid = true;
4656
}
4757
catch { }
4858
response.ConnectionStatus = status;
4959
return response;
5060
}
61+
62+
private JToken WriteJObject(JContainer container, string[] key, JToken value)
63+
{
64+
var thisKey = key.First();
65+
int indexer;
66+
if (key.Length > 2 || (key.Length == 2 && !int.TryParse(key.Last(), out indexer)))
67+
{
68+
var property = (JContainer)((JObject)container).GetValue(thisKey);
69+
if (property == null)
70+
{
71+
property = new JObject();
72+
((JObject)container).Add(thisKey, property);
73+
}
74+
var innerValue = WriteJObject(property, key.Skip(1).ToArray(), value);
75+
76+
//property.Add(new JValue(innerValue));
77+
//return property;
78+
return property;
79+
}
80+
81+
if (key.Length == 2 && int.TryParse(key.Last(), out indexer))
82+
{
83+
var property = ((JObject)container).Property(thisKey);
84+
if (property == null)
85+
{
86+
property = new JProperty(thisKey, new JArray());
87+
container.Add(property);
88+
}
89+
var jArray = (JArray)property.Value;
90+
jArray.Add(value);
91+
return property;
92+
}
93+
94+
{
95+
var property = new JProperty(thisKey, value);
96+
container.Add(property);
97+
return property;
98+
}
99+
}
100+
51101
/// <summary>
52102
/// Update the index settings for the default index
53103
/// </summary>
@@ -64,29 +114,9 @@ public ISettingsOperationResponse UpdateSettings(string index, IndexSettings set
64114

65115
string path = this.PathResolver.CreateIndexPath(index, "_settings");
66116
settings.Settings = settings.Settings
67-
.Where(kv => IndexSettings.UpdateWhiteList.Any(p =>
68-
{
69-
return kv.Key.StartsWith(p);
70-
}
71-
)).ToDictionary(kv => kv.Key, kv => kv.Value);
72-
73-
var sb = new StringBuilder();
74-
var sw = new StringWriter(sb);
75-
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
76-
{
77-
jsonWriter.WriteStartObject();
78-
jsonWriter.WritePropertyName("index");
79-
jsonWriter.WriteStartObject();
80-
foreach (var kv in settings.Settings)
81-
{
82-
jsonWriter.WritePropertyName(kv.Key);
83-
jsonWriter.WriteValue(kv.Value);
84-
}
85-
86-
jsonWriter.WriteEndObject();
87-
}
88-
string data = sb.ToString();
117+
.Where(kv => IndexSettings.UpdateWhiteList.Any(p => kv.Key.StartsWith(p))).ToDictionary(kv => kv.Key, kv => kv.Value);
89118

119+
string data = this.Serializer.Serialize(settings, Formatting.None);
90120
var status = this.Connection.PutSync(path, data);
91121

92122
var r = new SettingsOperationResponse();

src/Nest/ExposedInternals/ElasticSerializer.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Nest.Resolvers.Converters;
99
using Newtonsoft.Json;
1010
using Newtonsoft.Json.Converters;
11+
using Newtonsoft.Json.Linq;
1112

1213
namespace Nest
1314
{
@@ -17,6 +18,14 @@ public class ElasticSerializer
1718
private readonly PropertyNameResolver _propertyNameResolver;
1819
private readonly JsonSerializerSettings _serializationSettings;
1920

21+
private static readonly JsonConverter[] _defaultConverters =
22+
{
23+
new AnalyzerCollectionConverter(),
24+
new TokenFilterCollectionConverter(),
25+
new TokenizerCollectionConverter(),
26+
new CharFilterCollectionConverter()
27+
};
28+
2029
public ElasticSerializer(IConnectionSettings settings)
2130
{
2231
this._settings = settings;
@@ -79,6 +88,11 @@ internal T DeserializeInternal<T>(
7988
var jsonSettings = extraConverters.HasAny() || piggyBackJsonConverter != null
8089
? this.CreateSettings(extraConverters, piggyBackJsonConverter)
8190
: this._serializationSettings;
91+
92+
var jObjectValue = value as JObject;
93+
if (jObjectValue != null)
94+
return JsonSerializer.Create(jsonSettings).Deserialize<T>(jObjectValue.CreateReader());
95+
8296
var status = value as ConnectionStatus;
8397
if (status == null || !typeof(BaseResponse).IsAssignableFrom(typeof(T)))
8498
return JsonConvert.DeserializeObject<T>(value.ToString(), jsonSettings);
@@ -89,15 +103,15 @@ internal T DeserializeInternal<T>(
89103
internal JsonSerializerSettings CreateSettings(IList<JsonConverter> extraConverters = null, JsonConverter piggyBackJsonConverter = null)
90104
{
91105
var converters = extraConverters.HasAny()
92-
? extraConverters.ToList()
93-
: null;
106+
? extraConverters.Concat(_defaultConverters)
107+
: _defaultConverters;
94108
var piggyBackState = new JsonConverterPiggyBackState { ActualJsonConverter = piggyBackJsonConverter };
95109
var settings = new JsonSerializerSettings()
96110
{
97111
ContractResolver = new ElasticContractResolver(this._settings) { PiggyBackState = piggyBackState },
98112
DefaultValueHandling = DefaultValueHandling.Include,
99113
NullValueHandling = NullValueHandling.Ignore,
100-
Converters = converters,
114+
Converters = converters.ToList(),
101115
};
102116

103117
if (_settings.ModifyJsonSerializerSettings != null)
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Newtonsoft.Json;
4+
using Newtonsoft.Json.Linq;
5+
6+
namespace Nest.Resolvers.Converters
7+
{
8+
public class AnalysisSettingsConverter : JsonConverter
9+
{
10+
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
11+
{
12+
var analysisValue = (AnalysisSettings)value;
13+
writer.WriteStartObject();
14+
{
15+
if (analysisValue.Analyzers.Count > 0)
16+
{
17+
writer.WritePropertyName("analyzer");
18+
serializer.Serialize(writer, analysisValue.Analyzers);
19+
}
20+
21+
if (analysisValue.TokenFilters.Count > 0)
22+
{
23+
writer.WritePropertyName("filter");
24+
serializer.Serialize(writer, analysisValue.TokenFilters);
25+
}
26+
27+
if (analysisValue.Tokenizers.Count > 0)
28+
{
29+
writer.WritePropertyName("tokenizer");
30+
serializer.Serialize(writer, analysisValue.Tokenizers);
31+
}
32+
33+
if (analysisValue.CharFilters.Count > 0)
34+
{
35+
writer.WritePropertyName("char_filter");
36+
serializer.Serialize(writer, analysisValue.CharFilters);
37+
}
38+
}
39+
writer.WriteEndObject();
40+
41+
}
42+
43+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
44+
{
45+
JObject o = JObject.Load(reader);
46+
var result = existingValue as AnalysisSettings ?? new AnalysisSettings();
47+
48+
foreach (var rootProperty in o.Children<JProperty>())
49+
{
50+
if (rootProperty.Name.Equals("analyzer", StringComparison.InvariantCultureIgnoreCase))
51+
{
52+
result.Analyzers = serializer.Deserialize<IDictionary<string,AnalyzerBase>>(rootProperty.Value.CreateReader());
53+
}
54+
else if (rootProperty.Name.Equals("filter", StringComparison.InvariantCultureIgnoreCase))
55+
{
56+
result.TokenFilters = serializer.Deserialize<IDictionary<string, TokenFilterBase>>(rootProperty.Value.CreateReader());
57+
}
58+
else if (rootProperty.Name.Equals("tokenizer", StringComparison.InvariantCultureIgnoreCase))
59+
{
60+
result.Tokenizers = serializer.Deserialize<IDictionary<string, TokenizerBase>>(rootProperty.Value.CreateReader());
61+
}
62+
else if (rootProperty.Name.Equals("char_filter", StringComparison.InvariantCultureIgnoreCase))
63+
{
64+
result.CharFilters = serializer.Deserialize<IDictionary<string, CharFilterBase>>(rootProperty.Value.CreateReader());
65+
}
66+
}
67+
68+
return result;
69+
}
70+
71+
private void ReadCharFilterJson(JsonSerializer serializer, JProperty rootProperty, AnalysisSettings result)
72+
{
73+
74+
}
75+
76+
private void ReadTokenizerJson(JsonSerializer serializer, JProperty rootProperty, AnalysisSettings result)
77+
{
78+
79+
}
80+
81+
private void ReadFilterJson(JsonSerializer serializer, JProperty rootProperty, AnalysisSettings result)
82+
{
83+
84+
}
85+
86+
private static Type _type = typeof(AnalysisSettings);
87+
public override bool CanConvert(Type objectType)
88+
{
89+
return objectType == _type;
90+
}
91+
92+
public override bool CanRead
93+
{
94+
get { return true; }
95+
}
96+
}
97+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Newtonsoft.Json;
4+
using Newtonsoft.Json.Linq;
5+
6+
namespace Nest
7+
{
8+
9+
public class AnalyzerCollectionConverter : JsonConverter
10+
{
11+
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
12+
{
13+
var items = (IDictionary<string, AnalyzerBase>)value;
14+
writer.WriteStartObject();
15+
foreach (var item in items)
16+
{
17+
writer.WritePropertyName(item.Key);
18+
serializer.Serialize(writer, item.Value);
19+
}
20+
writer.WriteEndObject();
21+
}
22+
23+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
24+
{
25+
JObject o = JObject.Load(reader);
26+
var result = existingValue as Dictionary<string, AnalyzerBase> ?? new Dictionary<string, AnalyzerBase>();
27+
28+
foreach (var childProperty in o.Children<JProperty>())
29+
{
30+
var propertyName = childProperty.Name;
31+
var typeProperty = ((JObject)childProperty.Value).Property("type");
32+
typeProperty.Remove();
33+
34+
var typePropertyValue = typeProperty.Value.ToString();
35+
Language language;
36+
if (Enum.TryParse(typePropertyValue, true, out language))
37+
{
38+
typePropertyValue = "Language";
39+
}
40+
41+
var itemType = Type.GetType("Nest." + typePropertyValue + "Analyzer", false, true);
42+
AnalyzerBase item;
43+
if (itemType == typeof(LanguageAnalyzer))
44+
{
45+
item = new LanguageAnalyzer(language);
46+
serializer.Populate(childProperty.Value.CreateReader(), item);
47+
}
48+
else if (itemType != null)
49+
{
50+
item = serializer.Deserialize(childProperty.Value.CreateReader(), itemType) as AnalyzerBase;
51+
}
52+
else
53+
{
54+
continue;
55+
}
56+
57+
result[propertyName] = item;
58+
}
59+
return result;
60+
}
61+
62+
public override bool CanConvert(Type objectType)
63+
{
64+
return typeof(IDictionary<string,AnalyzerBase>).IsAssignableFrom(objectType);
65+
}
66+
67+
public override bool CanRead
68+
{
69+
get { return true; }
70+
}
71+
}
72+
}

0 commit comments

Comments
 (0)