.net ElasticSearch-Sql 扩展类
官方提供的是java sdk,并支持jdbc方式的查询结果输出;但是却没有.net sdk的支持。
开发 ElasticSearch-Sql 第三方开源项目的.net sdk,未来集成入bsf框架。(已使用,但未进行大范围使用测试,欢迎交流并抛砖引玉)
参考ElasticSearch-Sql 开源地址:https://github.com/NLPchina/elasticsearch-sql
1)支持将查询结果转换成datatable形式,便于界面绑定和数据导出等。
2)代码简单易懂,便于改进并提高稳定性和性能。(拷贝立即使用)
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
/*by 车江毅 欢迎交流,一起完善之。.net 开源,因你更美好*/
namespace BSF.ElasticSearch
{
public class EsSqlProvider
{
private string url;
private HttpClient client = new HttpClient();
public EsSqlProvider(string ip,int port)
{
this.url = string.Format("http://{0}:{1}/_sql",ip,port);
} public EsSqlProvider(string url)
{
this.url = url.TrimEnd('/')+"/_sql";
} public Result Post(string sql)
{
//var http = new BSF.Api.HttpProvider();
//var dic = new Dictionary<string, string>();
//dic.Add("",sql); var content = new StringContent(sql);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var json = PostBase(content); return new BSF.Serialization.JsonProvider().Deserialize<Result>(json); } public DataTable Query(string sql)
{
var result = Post(sql);
if (result.aggregations != null && result.aggregations.Count > )
{
var first = result.aggregations.First();
//groupby 统计方式
if (first.Value != null && first.Value.buckets != null && first.Value.buckets.Count > )
{
DataTable dataTable = new DataTable("es-groupby");
//以第一列为准,填充列
{
var t = first.Value.buckets[];
dataTable.Columns.Add(new DataColumn(first.Key, ColumnType((GetValue((object)t["key"])).GetType())));
foreach (var c in t)
{
if (c.Key != "doc_count"&&c.Key!= "key")
{ dataTable.Columns.Add(new DataColumn(c.Key, (GetValue(c.Value)).GetType())); }
}
}
//填充值
foreach (var b in first.Value.buckets)
{
DataRow dataRow = dataTable.NewRow();
dataRow[first.Key] = b["key"];
foreach (var c in b)
{
if(dataTable.Columns.Contains(c.Key))
dataRow[c.Key] = GetValue(c.Value);
}
dataTable.Rows.Add(dataRow);
}
return dataTable; }
else if (first.Value != null&& first.Value.value!=null)
{
DataTable dataTable = new DataTable("es-aggregations");
//常规统计方式
foreach (var o in result.aggregations)
{
dataTable.Columns.Add(new DataColumn(o.Key, ColumnType((GetValue((object)o.Value)).GetType())));
}
DataRow dataRow = dataTable.NewRow();
foreach (var o in result.aggregations)
{
if (dataTable.Columns.Contains(o.Key))
dataRow[o.Key] = GetValue(o.Value);
}
dataTable.Rows.Add(dataRow);
return dataTable;
}
}
else if (result.sources != null && result.sources.Count > )
{
DataTable dataTable = new DataTable("es-sources");
var first = result.sources.First();
foreach (var item in ((Dictionary<string,dynamic>)first))
{
dataTable.Columns.Add(new DataColumn(item.Key, ColumnType((GetValue((Object)item.Value)).GetType())));
}
foreach (dynamic m in result.sources)
{
DataRow dataRow = dataTable.NewRow();
foreach (var item in ((Dictionary<string, dynamic>)m))
{
if (dataTable.Columns.Contains(item.Key))
dataRow[item.Key] = GetValue(item.Value);
}
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
return null;
} private Type ColumnType(Type type)
{
if (type.IsArray)
{
return typeof(string);
}
else
return type;
} private Object GetValue(Object value)
{
if (value != null && value is Array)
return new BSF.Serialization.JsonProvider().Serializer(value);
if (value != null && (value.GetType().IsValueType || value is String))
return value;
if (value != null && value is Dictionary<string, dynamic>)
{
var valuet = (Dictionary<string, dynamic>)value;
if( valuet.ContainsKey("value_as_string"))
return GetValue(valuet["value_as_string"]);
if (valuet.ContainsKey("value"))
return GetValue(valuet["value"]);
}
if (value != null && value.GetType().GetProperty("value")!=null)
{
var p= value.GetType().GetProperty("value_as_string");
if (p!=null&&p.GetValue(value)!=null)
return p.GetValue(value);
p = value.GetType().GetProperty("value");
if (p != null && p.GetValue(value) != null)
return p.GetValue(value);
}
return new BSF.Serialization.JsonProvider().Serializer(value);
} private Object GetPropertyValue(Object obj, string property)
{
var p = obj.GetType().GetProperty(property);
if (p != null)
return p.GetValue(obj);
return null;
} private string PostBase(HttpContent content)
{
//此处未来需要添加HttpClient连接池,复用连接
//using (var client = new HttpClient())
//{
var result = client.PostAsync(url, content).Result;
string resultContent = result.Content.ReadAsStringAsync().Result;
return resultContent;
//}
} public class Result{ public Hits hits { get; set; }
public Dictionary<string, aggregation> aggregations {get;set;} public List<dynamic> sources { get {
List<dynamic> rs = new List<dynamic>();
foreach (var h in hits.hits)
{
rs.Add(h._source);
}
return rs;
} } public class aggvalue
{
public dynamic value { get; set; }
public string value_as_string { get; set; }
}
public class aggregation: aggvalue
{
public List<Dictionary<string, dynamic>> buckets { get; set; }
}
public class Hits {
public int total { get; set; }
public List<hit> hits { get; set; }
}
public class hit {
public string _index { get; set; }
public string _type { get; set; }
public string _id { get; set; } public string _score { get; set; } public dynamic _source { get; set; }
} }
}
}
欢迎交流,为了更好的完善之,开源QQ群: .net 开源基础服务 238543768
by 车江毅
.net ElasticSearch-Sql 扩展类的更多相关文章
- Mybatis逆向生成使用扩展类
1.背景介绍 用的mybatis自动生成的插件,然而每次更改数据库的时候重新生成需要替换原有的mapper.xml文件,都要把之前业务相关的sql重新写一遍,感觉十分麻烦,就想着把自动生成的作为一个基 ...
- 针对thinkphp 5框架存储过程bug而重写的存储过程的扩展类
近期用tp5框架调取存储过程发现有bug,借鉴了一些官方的函数.以及找了个mysqli的类把存储过程重新写了个扩展类,下面两个类直接放置项目extend目录的stored(这个文件夹名称请按个人习惯命 ...
- C# 扩展类
C# 中提供一个非常实用的供能,扩展方法(Extension method) 扩展方法是通过额外的静态方法扩展现有的类型.通过扩展方法,可以对已有类型做自己想做的相关扩展.方法:定义静态类,扩展方法也 ...
- 一个简单的ORM制作(SQL帮助类)
一个简单的ORM制作大概需要以下几个类: SQL执行类 CURD操作类 其他酱油类 先从SQL执行类说起,可能会涉及数据库的迁移等问题,所以需要定义一个接口以方便迁移到其他数据库, 事务没提供命名,若 ...
- tp中调用PHP系统扩展类
例如使用Redis扩展类: use Reids; $redis = new Redis();
- Java+7入门经典 - 6 扩展类与继承 Part 1/2
第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...
- Thinkphp编辑器扩展类kindeditor用法
一, 使用前的准备. 使用前请确认你已经建立好了一个Thinkphp站点项目. 1,Keditor.class.php和JSON.class.php 是编辑器扩展类文件,将他们拷贝到你的站点项目的Th ...
- 扩展javascript扩展(类,对象,原型)
扩展javascript扩展(类,对象,原型)
- 使用JDBC连接ElasticSearch6.3(ElasticSearch SQL JDBC)
使用JDBC连接ElasticSearch6.3(ElasticSearch SQL JDBC) https://blog.csdn.net/scgaliguodong123_/article/det ...
- 颜色扩展类--ColorExtensions
/// <summary> /// 颜色扩展类 /// </summary> public static class ColorExtensions { /// <sum ...
随机推荐
- jQuery UI 入门之实用实例
jQuery UI 入门 jQuery UI 简介 jQuery UI 是一个建立在 jQuery JavaScript 库上的小部件和交互库,您可以使用它创建高度交互的 Web 应用程序.无论您是创 ...
- cpp(第十七章)
1.baseic_ostream<charT,traits>& write(const char_type *s,streamsize n),cout.write()第一个参数提供 ...
- 获取Skype用户IP地址
#!/usr/bin/env bash ESC_SEQ="\x1b[" COL_RESET=$ESC_SEQ"39;49;00m" COL_RED=$ESC_S ...
- 使用HttpClient 调用Web Api
C#4.5 添加了异步调用Web Api . 如果你的项目是4.5以上版本,可以直接参考官方文档. http://www.asp.net/web-api/overview/web-api-client ...
- 并行模式库PPL应用实战(一):使用task类创建并行任务
自 VS2010 起,微软就在 CRT 中集成了并发运行时(Concurrency Runtime),并行模式库(PPL,Parallel Patterns Library)是其中的一个重要组成部分. ...
- 对象级别锁 vs 类级别锁 – Java
同步针对的是多线程.同步的方法或代码块同时只能由一个线程执行. Java支持多线程来执行.这可能会导致两个或多个线程访问同一个字段或对象.同步是一个使所有并发执行的线程同步的过程.同步避免了由于共享内 ...
- find的用法
find在Linux系统中和其它工具,如sed.awk.grep等结合起来用,非常有用. 1.列出系统中所有属于root用户的“set uid”文件 #find / -perm 4755 –uid 0 ...
- java入门学习笔记之1(类的定义,代码的编译执行)
这篇文章讲解Java代码的基本执行过程 我们先抛开各种JAVA IDE,开发工具,只使用文本编辑器,以突出最本质的东西. 在Linux环境下,我们编辑一个文件: vim HelloWorld.java ...
- PHP的魔法方法
PHP将所有以__(两个下划线)开头的类方法保留为魔术方法.所以在定义方法是,除了魔术方法,建议不要用两个下划线前缀. 魔术方法(Magic methods)有 __construct(),__des ...
- Swift3 访问权限fileprivate和 open
在swift 3中新增加了两种访问控制权限 fileprivate和 open. 下面结合网上资料和个人理解整理一下两个属性的原理与介绍. fileprivate 在原有的swift中的 privat ...