.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 ...
随机推荐
- git 入门教程之版本管理
版本管理 背景 在上一节中我们已经成功创建版本库并且已经添加test.txt等文件,这一节我们继续讲解如何进行版本控制. 首先我们先查看test.txt 文件有什么内容吧! # 查看文件内容 $ ca ...
- 浅析C/C++中的switch/case陷阱
浅析C/C++中的switch/case陷阱 先看下面一段代码: 文件main.cpp #include<iostream> using namespace std; int main(i ...
- android 可以精确到秒级的时间选择器
android自带的时间选择器只能精确到分,但是对于某些应用要求选择的时间精确到秒级,此时只有自定义去实现这样的时间选择器了.下面介绍一个可以精确到秒级的时间选择器. 先上效果图: 下面是工程目录: ...
- 关于在ROS kinetic下arbotix报错的问题
最近在学习ros过程中 出现了一个包错误 ERROR:cannot launch node of type [arbotix_python/arbotix_driver]:arbotix_pytho ...
- PostgreSQL date_trunc() 和timestamp
timestamp 01.SELECT now()::timestamp + '1 year'; 02.SELECT now()::timestamp + '1 month'; 03.SELECT n ...
- ctypes库调用dll的个人见解
最近着手开发一个小东西涉及到了API接口的知识点, 第一次使用到了ctypes库,在网上找了一大圈,基本都是讲add.dll之后就没了. 就像下面这个: from ctypes import * dl ...
- java传输文件的简单方法
假设现在已经打包了一个文件(1233444333),要将这个文件传输给另一方: package file; import java.io.*; public class F_PasswordUnPas ...
- 3. svg学习笔记-基本形状和画笔属性
svg中可以绘制的基本图形有线段,矩形,多边形,圆,椭圆,分别来看一下这些基本图形: 线段 使用<line>元素创建一条线段,格式如下: <line x1=" start- ...
- Linux实时查询GPU使用命令
查看显存使用情况的命令: $ nvidia-smi 周期性地查看GPU使用情况则使用命令: $ watch -n nvidia-smi 其中数字10表示每十秒刷新一次GPU使用状态. 具体如下所示:重 ...
- AI学习---TensorFlow框架介绍[图+会话+张量+变量OP+API]
TensorFlow的数据流图 TensorFlow的结构分析: 图 + 会话 TensorFlow = 构图阶段(数据与操作的执行步骤被描绘出一个图) + 执行图阶段(使用回话执行构建好的图中操作) ...