mirror of https://github.com/ogoun/Zero.git
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							174 lines
						
					
					
						
							7.6 KiB
						
					
					
				
			
		
		
	
	
							174 lines
						
					
					
						
							7.6 KiB
						
					
					
				| using System;
 | |
| using System.Collections;
 | |
| using System.Collections.Generic;
 | |
| using System.Linq;
 | |
| using System.Text;
 | |
| using ZeroLevel.Qdrant.DataAttributes;
 | |
| using ZeroLevel.Qdrant.Models;
 | |
| using ZeroLevel.Services.ObjectMapping;
 | |
| using ZeroLevel.Services.Reflection;
 | |
| using ZeroLevel.Services.Serialization;
 | |
| 
 | |
| namespace ZeroLevel.Qdrant.Services
 | |
| {
 | |
|     public static class QdrantJsonConverter<T>
 | |
|     {
 | |
|         private static string KeywordToString(IMemberInfo member, object v)
 | |
|         {
 | |
|             var text = TypeHelpers.IsString(member.ClrType) ? v as string : v.ToString();
 | |
|             if (string.IsNullOrEmpty(text))
 | |
|             {
 | |
|                 return "null";
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 return $"\"{JsonEscaper.EscapeString(text)}\"";
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /*
 | |
|        integer - 64-bit integer in the range -9223372036854775808 to 9223372036854775807.      array of long
 | |
|        float - 64-bit floating point number.                                                   array of double
 | |
|        keyword - string value.                                                                 array of strings
 | |
|        geo - Geographical coordinates. Example: { "lon": 52.5200, "lat": 13.4050 }             array of lon&lat of double
 | |
|         */
 | |
|         private const string KYEWORD_TYPE = "keyword";
 | |
|         private const string GEO_TYPE = "geo";
 | |
|         private const string FLOAT_TYPE = "float";
 | |
|         private const string INTEGER_TYPE = "integer";
 | |
| 
 | |
|         public static string ConvertToJson(float[] vector)
 | |
|         {
 | |
|             return "[" + string.Join(", ", vector.Select(f => f.ConvertToString())) + "]";
 | |
|         }
 | |
|         public static string ConvertToJson(T value)
 | |
|         {
 | |
|             var json = new StringBuilder();
 | |
| 
 | |
|             var map = TypeMapper.Create<T>();
 | |
|             foreach (var member in map.Members)
 | |
|             {
 | |
|                 var val = member.Getter(value);
 | |
|                 var type = KYEWORD_TYPE;
 | |
| 
 | |
|                 var attributes = member.Original.GetCustomAttributes(typeof(QdrantAttribute), true);
 | |
|                 if (attributes != null && attributes.Any())
 | |
|                 {
 | |
|                     var dataAttribute = attributes[0];
 | |
|                     if (dataAttribute is KeywordAttribute)
 | |
|                     {
 | |
|                         type = KYEWORD_TYPE;
 | |
|                     }
 | |
|                     else if (dataAttribute is FloatAttribute)
 | |
|                     {
 | |
|                         type = FLOAT_TYPE;
 | |
|                     }
 | |
|                     else if (dataAttribute is IntegerAttribute)
 | |
|                     {
 | |
|                         type = INTEGER_TYPE;
 | |
|                     }
 | |
|                     else if (dataAttribute is GeoAttribute)
 | |
|                     {
 | |
|                         type = GEO_TYPE;
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     var item_type = member.ClrType;
 | |
|                     // autodetect type
 | |
|                     if (TypeHelpers.IsArray(item_type))
 | |
|                     {
 | |
|                         item_type = item_type.GetElementType();
 | |
|                     }
 | |
|                     else if (TypeHelpers.IsEnumerable(item_type))
 | |
|                     {
 | |
|                         item_type = TypeHelpers.GetElementTypeOfEnumerable(item_type);
 | |
|                     }
 | |
|                     if (item_type == typeof(float) || item_type == typeof(double) || item_type == typeof(decimal))
 | |
|                     {
 | |
|                         type = FLOAT_TYPE;
 | |
|                     }
 | |
|                     else if (item_type == typeof(int) || item_type == typeof(long) || item_type == typeof(byte) ||
 | |
|                         item_type == typeof(short) || item_type == typeof(uint) || item_type == typeof(ulong) ||
 | |
|                         item_type == typeof(ushort))
 | |
|                     {
 | |
|                         type = INTEGER_TYPE;
 | |
|                     }
 | |
|                     else if (item_type == typeof(Location))
 | |
|                     {
 | |
|                         type = GEO_TYPE;
 | |
|                     }
 | |
|                 }
 | |
|                 switch (type)
 | |
|                 {
 | |
|                     case KYEWORD_TYPE:
 | |
|                         if (TypeHelpers.IsEnumerable(member.ClrType) && TypeHelpers.IsString(member.ClrType) == false)
 | |
|                         {
 | |
|                             var arr = val as IEnumerable;
 | |
|                             json.Append($"\"{member.Name.ToLowerInvariant()}\": {{ \"type\": \"keyword\", \"value\": [ {string.Join(", ", E(arr).Select(v => KeywordToString(member, v)))}] }},");
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             json.Append($"\"{member.Name.ToLowerInvariant()}\": {{ \"type\": \"keyword\", \"value\":{KeywordToString(member, val)} }},");
 | |
|                         }
 | |
|                         break;
 | |
|                     case GEO_TYPE:
 | |
|                         if (TypeHelpers.IsEnumerable(member.ClrType) && TypeHelpers.IsString(member.ClrType) == false)
 | |
|                         {
 | |
|                             var arr = val as IEnumerable;
 | |
|                             json.Append($"\"{member.Name.ToLowerInvariant()}\": {{ \"type\": \"geo\", \"value\": [ {string.Join(",", E(arr).Select(v => v as Location).Where(l => l != null).Select(l => $" {{ \"lon\":{l.lon.ConvertToString()}, \"lat\":{l.lat.ConvertToString()} }}"))}] }},");
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             Location l = val as Location;
 | |
|                             if (l != null)
 | |
|                             {
 | |
|                                 json.Append($"\"{member.Name.ToLowerInvariant()}\": {{ \"type\": \"geo\", \"value\": {{ \"lon\":{l.lon.ConvertToString()}, \"lat\":{l.lat.ConvertToString()} }} }},");
 | |
|                             }
 | |
|                         }
 | |
|                         break;
 | |
|                     case FLOAT_TYPE:
 | |
|                         if (TypeHelpers.IsEnumerable(member.ClrType) && TypeHelpers.IsString(member.ClrType) == false)
 | |
|                         {
 | |
|                             var arr = val as IEnumerable;
 | |
|                             json.Append($"\"{member.Name.ToLowerInvariant()}\": {{ \"type\": \"float\", \"value\": [ {string.Join(",", E(arr).Select(v => Convert.ToDouble(v).ConvertToString()))}] }},");
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
| 
 | |
|                             json.Append($"\"{member.Name.ToLowerInvariant()}\": {{ \"type\": \"float\", \"value\": {Convert.ToDouble(val).ConvertToString()} }},");
 | |
|                         }
 | |
|                         break;
 | |
|                     case INTEGER_TYPE:
 | |
|                         if (TypeHelpers.IsEnumerable(member.ClrType) && TypeHelpers.IsString(member.ClrType) == false)
 | |
|                         {
 | |
|                             var arr = val as IEnumerable;
 | |
|                             json.Append($"\"{member.Name.ToLowerInvariant()}\": {{ \"type\": \"integer\", \"value\": [ {string.Join(",", E(arr).Select(v => Convert.ToInt64(v)))}] }},");
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             json.Append($"\"{member.Name.ToLowerInvariant()}\": {{ \"type\": \"integer\", \"value\": {Convert.ToInt64(val)}  }},");
 | |
|                         }
 | |
|                         break;
 | |
|                 }
 | |
|             }
 | |
|             if (json[json.Length - 1] == ',')
 | |
|             {
 | |
|                 json.Remove(json.Length - 1, 1);
 | |
|             }
 | |
|             return json.ToString();
 | |
|         }
 | |
| 
 | |
|         private static IEnumerable<object> E(IEnumerable e)
 | |
|         {
 | |
|             if (e != null)
 | |
|             {
 | |
|                 foreach (var i in e)
 | |
|                 {
 | |
|                     yield return i;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |