官方提供的是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 扩展类的更多相关文章

  1. Mybatis逆向生成使用扩展类

    1.背景介绍 用的mybatis自动生成的插件,然而每次更改数据库的时候重新生成需要替换原有的mapper.xml文件,都要把之前业务相关的sql重新写一遍,感觉十分麻烦,就想着把自动生成的作为一个基 ...

  2. 针对thinkphp 5框架存储过程bug而重写的存储过程的扩展类

    近期用tp5框架调取存储过程发现有bug,借鉴了一些官方的函数.以及找了个mysqli的类把存储过程重新写了个扩展类,下面两个类直接放置项目extend目录的stored(这个文件夹名称请按个人习惯命 ...

  3. C# 扩展类

    C# 中提供一个非常实用的供能,扩展方法(Extension method) 扩展方法是通过额外的静态方法扩展现有的类型.通过扩展方法,可以对已有类型做自己想做的相关扩展.方法:定义静态类,扩展方法也 ...

  4. 一个简单的ORM制作(SQL帮助类)

    一个简单的ORM制作大概需要以下几个类: SQL执行类 CURD操作类 其他酱油类 先从SQL执行类说起,可能会涉及数据库的迁移等问题,所以需要定义一个接口以方便迁移到其他数据库, 事务没提供命名,若 ...

  5. tp中调用PHP系统扩展类

    例如使用Redis扩展类: use Reids; $redis = new Redis();

  6. Java+7入门经典 - 6 扩展类与继承 Part 1/2

    第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...

  7. Thinkphp编辑器扩展类kindeditor用法

    一, 使用前的准备. 使用前请确认你已经建立好了一个Thinkphp站点项目. 1,Keditor.class.php和JSON.class.php 是编辑器扩展类文件,将他们拷贝到你的站点项目的Th ...

  8. 扩展javascript扩展(类,对象,原型)

     扩展javascript扩展(类,对象,原型)

  9. 使用JDBC连接ElasticSearch6.3(ElasticSearch SQL JDBC)

    使用JDBC连接ElasticSearch6.3(ElasticSearch SQL JDBC) https://blog.csdn.net/scgaliguodong123_/article/det ...

  10. 颜色扩展类--ColorExtensions

    /// <summary> /// 颜色扩展类 /// </summary> public static class ColorExtensions { /// <sum ...

随机推荐

  1. 织梦dedecms后台发布文章提示“标题不能为空”

    问题症状:V5.7登录后台后,发布英文标题没问题,发布中文会提示“标题不能为空”. 问题根源:htmlspecialchars在php5.4默认为utf8编码,gbk编码字符串经 htmlspecia ...

  2. 为什么使用dojo?dojo与jquery有什么不同?dojo适合什么开发场景?

    首先介绍一下dojo的特性: 1.Dojo是一个符合AMD规范的企业级框架(dojo是一个重量级框架) 2.Dojo全面支持异步加载JS机制(即:支持通过require异步加载JS模块,通过defin ...

  3. git clone https://github.com/istester/ido.git ,确提示“Failed to connect to 192.168.1.22 port 8080: Connection refused” 的解决办法 。

    不知道是否有同学遇到如下的问题: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo } span.s1 { } git clone ...

  4. 关于Oracle、SqlServer 的sql递归查询

    递归查询所有子节点 建人员表  hrmresource 主键     姓名   上级ID 层级关系:- 4      - 3           - 2                - 1      ...

  5. 信号处理——卷积(convolution)的实现

    作者:桂. 时间:2017-03-07  22:33:37 链接:http://www.cnblogs.com/xingshansi/p/6517301.html 前言 信号时域.频域对应关系,及其D ...

  6. 1.JAVA WEB 笔记中文乱码

    JAVA WEB 乱码问题解析 乱码原因 在Java Web开发过程中,经常遇到乱码的问题,造成乱码的原因,概括起来就是对字符编码和解码的方式不匹配. 既然乱码的原因是字符编码与解码的方式不匹配,那么 ...

  7. Bash命令行编辑

    1.Readline库和命令行编辑 bash shell提供了两个内置编辑器:emacs和vi,利用它们可以以交互模式对命令行列表进行编辑,这项特性是通过Readline库的软件包实现的.当使用命令行 ...

  8. 学习maven的各种问题

    1. The container 'Maven Dependencies' references non existing library 解决方法,将eclipse中maven插件中“resolve ...

  9. 原生js在绑定事件时不用获取id名可直接用id名绑定???

    <div id="btn"> 点击 </div> <script> btn.onclick=function(){ console.log(bt ...

  10. python网络爬虫之使用scrapy自动爬取多个网页

    前面介绍的scrapy爬虫只能爬取单个网页.如果我们想爬取多个网页.比如网上的小说该如何如何操作呢.比如下面的这样的结构.是小说的第一篇.可以点击返回目录还是下一页 对应的网页代码: 我们再看进入后面 ...